如何使函数等到使用node.js调用回调后

我有一个简化的函数,看起来像这样:

function(query) {
  myApi.exec('SomeCommand', function(response) {
    return response;
  });
}

基本上,我希望它调用myApi.exec,并返回在回调lambda中给出的响应。但是,上面的代码不起作用,只是立即返回。

只是出于非常骇人的尝试,我尝试了以下无效的方法,但是至少您了解了我要实现的目标:

function(query) {
  var r;
  myApi.exec('SomeCommand', function(response) {
    r = response;
  });
  while (!r) {}
  return r;
}

基本上,实现此目的的“ node.js /事件驱动”良好方式是什么?我希望我的函数等待,直到调用回调,然后返回传递给它的值。

泡芙小卤蛋2020/03/20 10:34:49

假设您有一个功能:

var fetchPage(page, callback) {
   ....
   request(uri, function (error, response, body) {
        ....
        if (something_good) {
          callback(true, page+1);
        } else {
          callback(false);
        }
        .....
   });


};

您可以像这样使用回调:

fetchPage(1, x = function(next, page) {
if (next) {
    console.log("^^^ CALLBACK -->  fetchPage: " + page);
    fetchPage(page, x);
}
});
猴子村村2020/03/20 10:34:49

这违反了非阻塞IO的目的-您在不需要阻塞时就将其阻塞 :)

您应该嵌套您的回调,而不是强迫node.js等待,或者在需要结果的回调中调用另一个回调r

如果您需要强制阻塞,则很可能是在考虑架构错误。

老丝Eva2020/03/20 10:34:49

如果您希望它非常简单,容易,不需要花哨的库就可以在节点上执行回调函数,然后再执行其他代码,就像这样:

//initialize a global var to control the callback state
var callbackCount = 0;
//call the function that has a callback
someObj.executeCallback(function () {
    callbackCount++;
    runOtherCode();
});
someObj2.executeCallback(function () {
    callbackCount++;
    runOtherCode();
});

//call function that has to wait
continueExec();

function continueExec() {
    //here is the trick, wait until var callbackCount is set number of callback functions
    if (callbackCount < 2) {
        setTimeout(continueExec, 1000);
        return;
    }
    //Finally, do what you need
    doSomeThing();
}
Near西门2020/03/20 10:34:49

如果您不想使用回叫,则可以使用“ Q”模块。

例如:

function getdb() {
    var deferred = Q.defer();
    MongoClient.connect(databaseUrl, function(err, db) {
        if (err) {
            console.log("Problem connecting database");
            deferred.reject(new Error(err));
        } else {
            var collection = db.collection("url");
            deferred.resolve(collection);
        }
    });
    return deferred.promise;
}


getdb().then(function(collection) {
   // This function will be called afte getdb() will be executed. 

}).fail(function(err){
    // If Error accrued. 

});

有关更多信息,请参考:https : //github.com/kriskowal/q