Node.js - 在另一个方法完全执行后调用方法

时间:2014-02-20 15:47:39

标签: javascript node.js asynchronous promise rsvp-promise

我有两种简单的方法:

 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

3 个答案:

答案 0 :(得分:4)

由于node.js本质上是异步的,因此正常的命令式控制流不再起作用。您有多种选择,其中2种是使用最广泛的选项。

  1. 回调。您可以将第二个方法作为参数传递给第一个方法。然后在第一个任务完成后执行传递的回调。这种方法的缺点通常在节点社区中称为“回调地狱”。如果方法不是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()方法添加回调。