【问题标题】:How to rewrite this asynchronous method to return the value synchronously?如何重写此异步方法以同步返回值?
【发布时间】:2014-04-21 09:09:49
【问题描述】:

关于使 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 node.js asynchronous


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 使用生成器的解决方案会是什么样的?
      猜你喜欢
      • 2017-09-24
      • 2012-12-20
      • 2017-04-21
      • 2019-03-28
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      相关资源
      最近更新 更多