简体   繁体   中英

web workers behave differently in webkit than Firefox

I have a web application that works just fine in modern webkit-based browsers ( http://montecarlo-tester.appspot.com/ ). Basically it uses a webworker to fetch data from a server, and then sends it back after performing some computations.

It works just fine in Chrome/Safari (no errors in console), but when I try to use it in Firefox, it doesn't. I've deduced that somehow the variable 'iterations' is not set properly in Firefox. Unfortunately, Firefox lacks a debugger (for web workers), and javascript has functional scoping, so it's really hard to pinpoint where the problem is. I've posted the javascript code for my web worker, and I was wondering if anybody could point out where I went wrong:

importScripts('/static/js/mylibs/jquery.hive.pollen-mod.js');


$(function (data) {
    main();
    //while(main());
    close();
});

function main() {
    //make an ajax call to get a param
    var iterations//value will be set by server response
    var key//key of the datastore object
    var continueloop = true;
    p.ajax.post({
        url:'/getdataurl',
        dataType: "json",
        success: function(responseText){
            if (responseText === null) {
                var workermessage = {
                    "log":"responseText is null. Either the server has issues or we have run out of stuff to compute."
                };
                $.send(workermessage);
                continueloop = false;
            }
            iterations = responseText.iterationsjob;
            key = responseText.key;      
        }
    });

    if (continueloop === false) {
        return false;
    }

//here is where I think the problems begin. In chrome/safari, iterations = 1000. 
//In Firefox however, iterations = null. As a result, everything after that does not work.

    var i,x,y,z;
    var count = 0;
    var pi;
    start = new Date();
    for (i=0;i<iterations;i++) {
        x = Math.random();
        y = Math.random();
        z = x*x+y*y;
        if(z<=1.0){
            count++;
        }
    }//end for loop
    pi = count/(iterations)*4.0;
    end = new Date();
    result = {
        "estimated_pi":pi,
        "num_iter":iterations,
        "duration_ms":end.valueOf()-start.valueOf(),
        "key":key
    };
    //send results to the server
    p.ajax.post({
        url: "/resultshandler",
        dataType:'json',
        data: result,
        success: function()
        {
            //do nothing!
        }
    });
    $.send(result);
    return true;//persists the loop
}

You're doing an async XHR, then immediately doing a loop trying to use its results. I have no idea why this possibly works in Chrome, but it's definitely racy. Have you tried passing "sync:true" in your post options?

Edit: Oh, nevermind. I see why your code works. The hive.pollen script has this wonderful bit:

sync: navigator.userAgent.toLowerCase().indexOf('safari/') != -1 ? false : true,

So it's doing a sync XHR in Chrome/Safari and an async one in everything else, by default (because it passes options.sync as the value for the async argument to XMLHttpRequest.open , which is backwards, but whatever; it does mean that you actually need to pass sync: false at the callsite to get sync behavior). And since you don't specify whether you want sync or async, you get sync in Chrome and async in Firefox.

Oh, and the script has this wonderful comment before that line:

//  TODO: FIX THIS.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM