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

时间:2014-04-21 09:09:50

标签: javascript node.js asynchronous

关于使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。我在想睡眠循环是否有效?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

如果您想从异步函数获得实际返回值,除了使用生成器或Promises之外别无选择。 您将始终必须包装您的函数,或直接返回Promises。

最好的承诺库之一是bluebird,它还解释了如何以及为何使用它(https://github.com/petkaantonov/bluebird#what-are-promises-and-why-should-i-use-them)。如果您需要与节点样式回调接口或需要公开依赖于节点样式回调而不是promises的API,它还会提供一些方便的方法来自动进行转换。