setInterval / setTimeout检查变量的值

时间:2014-01-05 06:02:07

标签: javascript settimeout setinterval

我正在编写一些依赖于一些异步方法调用的javascript,

var one = asyncCall();
var two = differentAsyncCall();

我知道我可以处理任何一个返回值,如此

var one = asyncCall(function(results){
  //do stuff
});
var two = differentAsyncCall(function(results){
//do more
});

我想用它们执行操作,所以要做到这一点,必须完成两个异步调用。我知道我可以做类似的事情:

asyncCall(function(results){

  var firstReturn = results;

  differentAsyncCall(function(results2){
    var secondReturn = results2;
    //do stuff now that they're both defined.
  });   

});

我很好奇是否可以使用setInterval或setTimeout来执行以下操作:

var one = asyncCall(function(results){
  return results;
});
var two = differentAsyncCall(function(results){
  return results;
});

window.setInterval(function(){
  if( one && two){
    //do stuff now that they're defined
    //remove the timer
  }
},250);

3 个答案:

答案 0 :(得分:3)

这是一个名为Promises的概念,可以在这里使用。 Promise是延迟对象概念的一部分。

这个想法是将异步调用分配给两个变量。当两个变量都可用时,请采取一些操作,这就是您要做的事情。

我使用过jQuery版本,其文档可以在这里找到。 http://api.jquery.com/jquery.when/

很容易理解。我不知道如何在纯Javascript中实现它。你最好使用任何异步库

答案 1 :(得分:1)

这是使用Promises / Deferreds的一个很好的用例,但这是另一个概念,需要包含一个库(至少目前为止)。

当你使用纯javascript(没有库)时,可以在某处添加这个简单的帮助方法:

    function whenAll(promises, doneProperty, callback){
        promises[doneProperty] = true;
        for(var key in promises)
            if(promises[key] == false) return false;            
        if(callback) callback();
        return true;
    }

(以下示例包含3个需要完成的异步调用)

然后你会这样做:

//This object contains all the async calls needed to be completed, key is the name
var promises = {"asyncCall1": false, "asyncCall2": false, "asyncCall3": false};

//And the magic comes here:
var results1, results2, results3;  //These will contain the results
(function(whenAllCallback){
    asyncCall1(function(results){
      results1 = results;
      whenAll(promises, "asyncCall1", whenAllCallback);
    });
    asyncCall2(function(results){
      results2 = results;
      whenAll(promises, "asyncCall2", whenAllCallback);
    });
    asyncCall3(function(results){
      results3 = results;
      whenAll(promises, "asyncCall3", whenAllCallback);
    });    
})(function(){
    //This executes when all calls have been completed
    alert(results1);
    alert(results2);
    alert(results3);
});

请注意,3个异步调用可以按任何顺序结束,并且在完成所有操作后,将根据需要执行回调。

这种语法在开始时可能很难,但是一旦你习惯它,它就变得容易了。在进入真正的承诺之前,您可以使用此代码。

来自玻利维亚拉巴斯的欢呼声

答案 2 :(得分:0)

我之前的答案的另一个版本,它接受返回值作为最终回调中的参数,并使用promises数组而不是object(更简单):

function whenAll(promisesKeys, doneProperty, callback, returnValue){
    var returnValues = promisesKeys.returnValues = promisesKeys.returnValues || new Array(promisesKeys.length);
    returnValues[promisesKeys.indexOf(doneProperty)] = (returnValue === undefined ? null : returnValue);
    for(var i=0; i < returnValues.length; i++)
        if(returnValues[i] === undefined) return false;
    delete promisesKeys.returnValues;
    callback.apply(this, returnValues);
    return true;
}

这是一个示例用法:

//This array contains all the async calls keys needed to be completed
var promisesKeys = ["call1", "call2", "call3"];

//And the magic comes here:
(function(whenAllCallback){
    //Intentionally call the methods in different order
    asyncCall2(function(results){
      whenAll(promisesKeys, "call2", whenAllCallback, results);
    });
    asyncCall1(function(results){
      whenAll(promisesKeys, "call1", whenAllCallback, results);
    });
    asyncCall3(function(results){
      whenAll(promisesKeys, "call3", whenAllCallback, results);
    });    
})(function(results1, results2, results3){   //These come in the same order as in the initial array
    //This executes when all calls have been completed
    console.log("ALL FINISHED:!");
    console.log(results1);
    console.log(results2);
    console.log(results3);
});

jsfiddle:http://jsfiddle.net/edgarinvillegas/B3x72/

干杯