【问题标题】:Get the value of a Javascript Promise in a synchronous way [duplicate]以同步方式获取 Javascript Promise 的值 [重复]
【发布时间】:2016-05-14 07:36:17
【问题描述】:

我需要以同步方式获取 Javascript Promise 对象的值。

我知道它是如何在 JavaScript 中工作的 Promise 对象,它的优点,以及如何使用 then 方法处理值,但是有一些用例,特别是 Node.js(但这可能适用于浏览器引擎),您只需要返回值,但您正在调用返回 Promise 对象的 API,并且您无法更改该 API 或使用者 API 的签名。

例如,在 Java 语言中,您有 get() 方法,它允许您在必要时等待完成操作(阻止执行),然后返回其结果。即使您有一个get(timeout,unit),如果等待超时,则在启动之前等待的最长时间是TimeoutException

我遇到的问题是这样的:

api1.setCallBackThatHasToReturnANoPromiseValue(
  function(p1, p2) {
    return api2.getPromisedValue(p1,p2)        // This returns a Promise
                                       .get()  // -> but something like this
                                               //    could get the value in a sync way
  }
);

谁能告诉我是否可以通过异步编程解决这个问题?

不管我的具体问题可以用异步代码解决,有一种方法可以以同步方式获取 Promise 的值(我知道它会阻止执行和所有性能问题,请避免 "bla bla...").

【问题讨论】:

  • 我认为您对这些概念感到困惑。承诺是必要的,因为代码异步的。如果可以同步完成,就不需要 Promises 开始了。如果这是在 NodeJS 中,它们确实有许多方法的同步版本,但如果你不可用,那么答案是“不”。
  • 承诺在异步世界中有效。一旦某些东西被异步触发,就无法让它再次同步。
  • @squint 正如我所说,我正在处理两个不同的 API,所以我无法改变一个使用 promise 而另一个不使用的事实。你能看到示例代码并告诉我如何解决这个问题吗?
  • @edwin-dalorzo:说“没有办法……”和“在Javascript中没有办法”是不一样的,要求很简单可以在许多平台上完成,例如我提供的 Java 示例。您是在告诉我,在 Javascript 中,或者更具体地说,使用标准 Promise 对象无法完成?
  • @amit: 类似但不重复,可能是关于 Promise 对象的具体问题,而不是像 jQuery 或其他 API 使用的任何其他异步方法,即使我提供了一个代码示例,其中存在不同的问题另一个问题,所以我认为没有必要关闭或修改问题。如果您同意,您可以取消将问题标记为重复吗?

标签: javascript node.js promise


【解决方案1】:

我需要获取 Javascript Promise 对象的值 同步方式。

你不能。如果 API 返回一个 Promise,那是因为操作是异步的。在您的函数返回时,该值根本不知道,Javascript 不提供任何机制来等待返回前的结果。

相反,您必须针对异步响应进行设计,而您的调用者必须针对异步响应编写代码。由于您已经在使用 Promise,这意味着您的调用者需要在 Promise 上使用 .then() 处理程序才能访问异步结果,并且 .then() 处理程序将在未来某个时间被调用,在 API 调用很久之后已经回来了。

重要的是要了解浏览器和 node.js 中的 Javascript 与 Java 根本不同。这些 Javascript 环境是单线程和事件驱动的。这意味着您不能在返回之前阻止并等待某些事情发生。相反,您必须返回并让事件队列运行,以便最终可以处理您的异步结果并触发回调。如果您确实尝试阻止并等待结果(有些人尝试进行繁忙的循环,只循环几秒钟以模拟可能使用另一种语言的sleep() 调用),您将遇到死锁,因为结果可能在您停止阻塞之前不会被处理,但在结果准备好之前您不会停止阻塞。你最终会陷入无限循环。

因此,您必须学习在 Javascript 中为异步响应编程,或者通过普通回调或使用 Promise 及其关联的 .then() 处理程序。而且,该异步结果的所有消费者都必须知道它是异步的并相应地进行编程。


此外,promise 是未来值的表示。您只能使用.then() 处理程序访问它,当(将来的某个时间)值准备好或发生错误时将调用该处理程序。没有同步的方式从 Promise 中获取值。

【讨论】:

    【解决方案2】:

    如果你可以使用 ES2016(ES7) 特性(通过 Babeljs 或库),你可以使用 async-await。

    使用 async-await 可以将函数定义为具有异步代码,然后使用 await 关键字等待来自异步函数的响应。异步函数需要返回一个承诺。 Async-await 让您可以像编写同步代码一样编写异步代码。

    【讨论】:

    • 我现在不能使用 ES7,但看起来很棒,我希望这些功能能很快在 Node.js 的下一个稳定版本中提供。
    • @Mrdev:确实这是一个不错的功能,但是您很清楚,即使此功能今天可用,它也无助于您当前的情况。正如@kevintechie 所写,“异步函数需要返回一个承诺。”。这只是语法糖,并没有添加任何你已经可以做的事情。它只是清理它。
    猜你喜欢
    • 2019-04-25
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 2013-03-27
    • 2016-08-13
    • 1970-01-01
    相关资源
    最近更新 更多