如何使函数等到使用 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/event 驱动”方式来解决这个问题?我希望我的函数等到回调被调用,然后返回传递给它的值。

原文由 Chris 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 776
2 个回答

这样做的“好的 node.js /事件驱动”方式是 不等待

与使用事件驱动系统(如节点)时的几乎所有其他事情一样,您的函数应该接受一个回调参数,该参数将在计算完成时调用。调用者不应等待正常意义上的“返回”值,而是发送将处理结果值的例程:

 function(query, callback) {
 myApi.exec('SomeCommand', function(response) {
 // other stuff here...
 // bla bla..
 callback(response); // this will "return" your value to the original caller
 });
 }

所以你不要这样使用它:

 var returnValue = myFunction(query);

但是像这样:

 myFunction(query, function(returnValue) {
 // use the return value here instead of like a regular (non-evented) return value
 });

原文由 Jakob 发布,翻译遵循 CC BY-SA 2.5 许可协议

实现此目的的一种方法是将 API 调用包装到承诺中,然后使用 await 等待结果。

 // Let's say this is the API function with two callbacks,
// one for success and the other for error.
function apiFunction(query, successCallback, errorCallback) {
    if (query == "bad query") {
        errorCallback("problem with the query");
    }
    successCallback("Your query was <" + query + ">");
}

// Next function wraps the above API call into a Promise
// and handles the callbacks with resolve and reject.
function apiFunctionWrapper(query) {
    return new Promise((resolve, reject) => {
        apiFunction(query,(successResponse) => {
            resolve(successResponse);
        }, (errorResponse) => {
            reject(errorResponse);
        });
    });
}

// Now you can use await to get the result from the wrapped api function
// and you can use standard try-catch to handle the errors.
async function businessLogic() {
    try {
        const result = await apiFunctionWrapper("query all users");
        console.log(result);

        // the next line will fail
        const result2 = await apiFunctionWrapper("bad query");
    } catch(error) {
        console.error("ERROR:" + error);
    }
}

// Call the main function.
businessLogic();

输出:

 Your query was <query all users>
ERROR:problem with the query

原文由 Timo 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题