1

I want to run several tasks in parallel and use queue.js of mbostock.I run the following code with using Sleep(),so expecting the other lighter tasks to be finished before the heavy tasks while all of the tasks executed at the same time.But following code result in executing tasks sequentially

2 1 test.html:128
1000 2 test.html:134
4 3 test.html:128
3000 4 test.html:134
6 5 test.html:128

while I was expecting something like(execute every tasks at same time but lighter tasks finish earlier):

2 1 test.html:128 
4 3 test.html:128
6 5 test.html:128    
1000 2 test.html:134
3000 4 test.html:134

What am I doing wrong? code:

function Sleep(ms) {
    var d1 = new Date().getTime();
    var d2 = new Date().getTime();
    while( d2 < (d1 + ms) ) {
        d2 = new Date().getTime();
    }
    return;
}

var tmp_list = [];
var normal = function(src){
    tmp_list.push(src);
    console.log(src,tmp_list.length);
}

var sleepy = function(src){
    Sleep(5000);
    tmp_list.push(src);
    console.log(src,tmp_list.length)
};

queue().defer(normal,2)
        .defer(sleepy,1000)
        .defer(normal,4)
        .defer(sleepy,3000)
        .defer(normal,6)
        .awaitAll(function(){});
user3164565
  • 67
  • 1
  • 7
  • Do you want to do it in the browser or in a node environment? In Javascript, _everything_ runs synchronously **except** input/output in the browser. – musically_ut Mar 24 '14 at 07:09
  • I want to run it on the browser or client side.I didn't know that input/output doesn't run synchronously in Javascript.Would you mention some good reference to understand those structure or philosophy of Javascript? – user3164565 Mar 24 '14 at 08:51
  • This SO question should clarify things a little bit: http://stackoverflow.com/questions/2035645/when-is-javascript-synchronous – musically_ut Mar 24 '14 at 08:56

1 Answers1

1

Javascript's model for concurrency is a bit different from other languages.

In Javascript, everything runs synchronously except input/output. This input/output usually takes the shape of AJAX calls. You can also explicitly yield control using the setTimeout function.

In your case, you are creating a busy loop while in Sleep function:

function Sleep(ms) {
    var d1 = new Date().getTime();
    var d2 = new Date().getTime();
    while( d2 < (d1 + ms) ) {
        d2 = new Date().getTime();
    }
    return;
}

This will keep the CPU busy humming along and not yield control until it is done. However, if you truly want to wait for the task to be over, you have to make use of the callback which the queue library provides to the function being called and use setTimeout:

 /* cb :: function (err, result) is added by queue library to the arg list */
function sleepy = function (src, cb) {
    setTimeout(function () {
        tmp_list.push(src);
        console.log(src, tmp_list.length);
        cb(); // no errors
    }, 5000);
}

Also, I suspect that your function after .awaitAll is not getting called either (since you are not using queue's callbacks). Try putting a console.log in there to verify this.

musically_ut
  • 34,028
  • 8
  • 94
  • 106
  • Wow,it fixed.Very interesting.Thank you! I didn't need to use callback as I just want to add result to global variables. – user3164565 Mar 24 '14 at 08:47