我有两种简单的方法:
function do(x,y){
if(x){
XHR1().success();
}
if(y){
XHR2().success();
}
}
function done(){
return something;
}
现在我想确保在done()
完成时调用do()
(** do()方法包含对Mysql DB的异步请求)
我怎样才能做到这一点?**
显然,这不会按顺序放置这些方法:
do(x=1,y=1);
done(); //this can run also if do() has not finished yet
所以我尝试了:
function do(x,y,_callback){
if(x){
XHR1().success();
}
if(y){
XHR2().success();
}
_callback();
}
function done(){
return something;
}
do(x=1,y=1,done()); // this won't work the same cause callback is not dependent by XHR response
这是我用于承诺的https://github.com/tildeio/rsvp.js/#arrays-of-promises
答案 0 :(得分:4)
由于node.js本质上是异步的,因此正常的命令式控制流不再起作用。您有多种选择,其中2种是使用最广泛的选项。
回调。您可以将第二个方法作为参数传递给第一个方法。然后在第一个任务完成后执行传递的回调。这种方法的缺点通常在节点社区中称为“回调地狱”。如果方法不是2,但更多,那么你必须越来越多地传递和嵌套回调,创建一个巨大的嵌套结构。
使用承诺。有许多库实现了promises模式。简而言之,promises允许您从每个方法返回Promise对象。承诺是一个对象,它将在未来完成其工作。它允许您调用方法,让它知道一旦完成需要发生什么。有关详细信息,请参阅此文章:Understanding promises in node.js
答案 1 :(得分:4)
我知道承诺,但我不知道怎么把它放在sintax中
假设XHR()
确实返回了一个承诺,那么这就是你的代码应该是这样的:
function do(x,y) {
var requests = [];
if (x)
requests.push( XHR1() );
if (y)
requests.push( XHR2() );
return RSVP.all(requests);
}
function done(){
return something;
}
do(1, 1).then(done);
答案 2 :(得分:1)
异步方法的流行模式是。
asyncFunc1(arguments, function(err, data){
if(err) throw err;
// Do your stuff
});
function asyncFunc1(arguments, callback) {
asyncFunc2(arg, function(err, data) {
if(err) return callback(err);
// Do your stuff
callback(null, result);
});
}
查看示例fs.readFile();
仍然使用回调而不是特定模式你可以使用这样的东西:
function do(x,y,_callback){
var count = 0;
if(x){
count++;
XHR1().success(checkDone);
}
if(y){
count++;
XHR2().success(checkDone);
}
function checkDone(){
count--;
if(!count) _callback();
}
}
function done(){
return something;
}
do(x=1,y=1,done());
计数器会跟踪您进行了多少次异步通话,并在完成所有操作后调用_callback
。但是您需要向XHR().success()
方法添加回调。