如何重写此异步方法以同步返回值

How to rewrite this asynchronous method to return the value synchronously?

本文关键字:异步方法 同步 返回值 何重写 重写      更新时间:2023-09-26

关于同步Nodejs/Javascript方法有很多问题,但到目前为止,我看到的答案涉及使用asyncfibrous等库。

但是要使用像fibrous这样的库,我必须用它们的包装器来包装我的函数。

我正在寻求一种解决方案,其中代码位于我的函数内(而不是在函数外包装它)。

例如,这是我的异步函数,它使用回调:

function myFunc(callback) {
  // Classic database fetch which is asynchronous
  db.find("foo", function(err, results) {
    callback(err, results);
  });
}

我想要的是函数返回结果:

function myFunc() {
  // Make this function synchronous, and return the result
  // ...
  return results;
}

我该怎么做?

再一次,我不想用其他函数包装myFunc。我在想睡眠循环是否有效?

不,不能使用循环来等待异步调用。Javascript是单线程的,因此需要将控制权返回到要调用的异步回调的主事件处理程序。如果运行循环,数据库查询完成的事件将在队列中等待,并且永远不会被处理。

你可以做的是返回一个承诺,而不是结果本身。这是一个跟踪回调是否被调用的对象,有一个回调可以放置结果的属性,并有一个在需要时获取结果的方法(它使用回调,因为一旦使用异步方法,就无法完全同步处理)。

如果您想要一个异步函数的实际返回值,除了使用生成器或Promises,您别无选择。您总是需要包装您的函数,或者直接返回Promises。

最好的promise库之一是bluebird,它还解释了如何以及为什么使用它(https://github.com/petkaantonov/bluebird#what-是的,是的,应该是的)。如果您需要与节点样式回调接口,或者需要公开依赖于节点样式回调而不是承诺的API,那么它还提供了一些自动化转换的方便方法。