猿问

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

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

我有一个简化的功能,如下所示:

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

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

只是为了一个非常hackish尝试,我尝试了下面没有工作,但至少你明白了我想要实现的目标:

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

基本上,什么是一个好的'node.js /事件驱动'的方式来解决这个问题?我希望我的函数等到调用回调,然后返回传递给它的值。


GCT1015
浏览 507回答 3
3回答

宝慕林4294392

“good node.js / event driven”这样做的方法就是不要等待。与使用像节点这样的事件驱动系统几乎所有其他内容一样,您的函数应该接受一个回调参数,该参数将在计算完成时调用。调用者不应该等待正常意义上的“返回”值,而是发送将处理结果值的例程: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});

动漫人物

实现此目的的一种方法是将API调用包装到promise中,然后使用await等待结果。//&nbsp;let's&nbsp;say&nbsp;this&nbsp;is&nbsp;the&nbsp;API&nbsp;function&nbsp;with&nbsp;two&nbsp;callbacks,//&nbsp;one&nbsp;for&nbsp;success&nbsp;and&nbsp;the&nbsp;other&nbsp;for&nbsp;errorfunction&nbsp;apiFunction(query,&nbsp;successCallback,&nbsp;errorCallback)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(query&nbsp;==&nbsp;"bad&nbsp;query")&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorCallback("problem&nbsp;with&nbsp;the&nbsp;query"); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;successCallback("Your&nbsp;query&nbsp;was&nbsp;<"&nbsp;+&nbsp;query&nbsp;+&nbsp;">");}//&nbsp;myFunction&nbsp;wraps&nbsp;the&nbsp;above&nbsp;API&nbsp;call&nbsp;into&nbsp;a&nbsp;Promise//&nbsp;and&nbsp;handles&nbsp;the&nbsp;callbacks&nbsp;with&nbsp;resolve&nbsp;and&nbsp;rejectfunction&nbsp;apiFunctionWrapper(query)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;Promise((resolve,&nbsp;reject)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;apiFunction(query,(successResponse)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resolve(successResponse); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;(errorResponse)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reject(errorResponse) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;});}//&nbsp;now&nbsp;you&nbsp;can&nbsp;use&nbsp;await&nbsp;to&nbsp;get&nbsp;the&nbsp;result&nbsp;from&nbsp;the&nbsp;wrapped&nbsp;api&nbsp;function//&nbsp;and&nbsp;you&nbsp;can&nbsp;use&nbsp;standard&nbsp;try-catch&nbsp;to&nbsp;handle&nbsp;the&nbsp;errorsasync&nbsp;function&nbsp;businessLogic()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;result&nbsp;=&nbsp;await&nbsp;apiFunctionWrapper("query&nbsp;all&nbsp;users"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(result); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;the&nbsp;next&nbsp;line&nbsp;will&nbsp;fail &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;result2&nbsp;=&nbsp;await&nbsp;apiFunctionWrapper("bad&nbsp;query"); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch(error)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.error("ERROR:"&nbsp;+&nbsp;error); &nbsp;&nbsp;&nbsp;&nbsp;}}//&nbsp;call&nbsp;the&nbsp;main&nbsp;functionbusinessLogic();输出:Your&nbsp;query&nbsp;was&nbsp;<query&nbsp;all&nbsp;users>ERROR:problem&nbsp;with&nbsp;the&nbsp;query
随时随地看视频慕课网APP
我要回答