Javascript同步 - 等待setTimeOut完成,如果可能,不进行回调

时间:2014-08-03 11:32:29

标签: javascript asynchronous timer synchronization

我试图创建一个网络游戏但由于javascript的单线程问题而遇到了麻烦。 我有一些这样的功能

function printNum(currentNum, targetNum, source, delay) {
    if(currentNum < targetNum) {
        currentNum++;
        setTimeout(function() {
            for(var i=0; i<source.length; i++) {
                source[i].innerHTML = ("<p>" + currentNum + "</p>");
            }
            printNum (currentNum, targetNum, source, delay);
        },delay);
    }
}

一次调用一些函数,由于setTimeOut()函数,它们异步进行。但是我需要我的代码在这些函数完全完成后运行(即不再有printNum递归)。我试图避免以后将所有代码放入回调函数,因为游戏在while循环中工作。我想创造这样的东西

while(condition is true){
    /*some functions*/
    /*asynchronous functions*/
    /*wait till all asynchronous functions to finish*/
    /*some functions*/
}

我应该创建一个特殊的类来处理它们(例如队列)吗?或者是否已有框架做同样的事情?或者只是修改我的代码?

很抱歉,如果我不清楚我的问题。我是这门语言的新手,真诚地感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

编辑:下面的原始代码有回调。没有回调的另一个控制例程是使用Promise / A +,在撰写本文时(2014年8月),Mozilla page表示它仍然是实验性的,并不是所有浏览器都完全支持。

基本上,承诺是这样的(在FireFox上): -

var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 400, "a"); });
var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 200, "b"); });
Promise.all([true, p1, p2]).then(function(values) {
  // values == [ true, 'a','b']
});

~~

使用async.js库,它允许您控制异步功能,轻微调整以添加对现有功能的回调。这是一段代码: -

/* start with some synchronous functions */

/* rewrite your async functions with callback, and use async.parallel() */
async.parallel([
    function(callback){ /*asynchronous functions*/
        setTimeout(function(){
            callback(null, 'one');
        }, 200);
    },
    function(callback){ /*asynchronous functions*/
        setTimeout(function(){
            callback(null, 'two');
        }, 100);
    }
],
// optional callback
function(err, results){
    // the results array will equal ['one','two'] even though
    // the second function had a shorter timeout.
    /* continue with some synchronous functions */
});

答案 1 :(得分:0)

感谢Alvin !!!我找到了使用async.js的解决方案。不得不说这是一个了不起的API。但是,维护起来可能非常困难。所以这里是异步函数:

function asychronousFn_1(callback){
     printNum(30,10,/*some source*/,200,callback);
}
function asychronousFn_2(callback){
     printNum(40,10,/*some source*/,300,callback);
}
function printNum(currentNum, targetNum, source, delay,callback) {
    if(currentNum < targetNum) {
        currentNum++;
        setTimeout(function() {
            for(var i=0; i<source.length; i++) {
                source[i].innerHTML = ("<p>" + currentNum + "</p>");
            }
            printNum (currentNum, targetNum, source, delay);
        },delay);
    }else{
         //Exiting the recursion
         callback(null,"I am continuing");
    }
}

基本上,回调方法会向异步API发出“完成”信号。 然后我们可以使用parallel函数异步调用函数

function doAllAsynchronousFn(callback){//package the parallel function to another function, which can also be used by async.js
     async.parallel([
        asynchronousFn_1,
        asynchronousFn_2
    ],
    // optional callback
    function(err, results){
        //executes after everything finishes
        callback(null,"continuing");
    });
}

我们可以使用aysnc.series()

链接其他功能
async.series([
    doAllAsynchronousFn,/*some other functions*/],/*a callback function*/
); 

现在,功能可以像电路(并联和串联)一样链接。再次感谢Alvin!

希望那些遇到麻烦的人觉得有帮助