我需要以同步方式获取Javascript Promise对象的值。
我知道Javascript中Promise对象的工作方式及其优点,以及如何使用then
方法处理值,但有一些用例,特别是Node.js(但是这也适用于浏览器引擎,你需要只返回值,但是你正在调用一个返回Promise对象的API,而你无法改变该API的签名或消费者API。 / p>
例如,在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的值(我知道它会阻止执行和所有性能问题,请避免< em>&#34; bla bla ...&#34; )。
答案 0 :(得分:4)
我需要获取一个Javascript Promise对象的值 同步方式。
你做不到。如果API返回一个promise,因为该操作是异步的。在函数返回时,该值尚未知晓,Javascript在返回之前没有提供任何等待结果的机制。
相反,您必须设计异步响应,并且调用者必须编写异步响应代码。由于您已经在使用promises,这意味着您的调用者需要在promise上使用.then()
处理程序来访问异步结果,并且.then()
处理程序将在未来的某个时间被调用, API调用之后已经返回。
了解浏览器和node.js中的Javascript与Java根本不同,这一点很重要。这些Javascript环境是单线程和事件驱动的。这意味着你不能阻止并等待返回之前发生的事情。相反,您必须返回并让事件队列运行,以便最终处理异步结果并触发回调。如果您确实尝试阻塞并等待结果(有些人尝试使用繁忙的循环,只需循环几秒钟来模拟可能在另一种语言中使用的sleep()
调用),那么您将遇到死锁,因为在您停止阻止之前无法处理结果,但在结果准备好之前您不会停止阻塞。你最终会得到一个无限循环。
因此,您必须学会在Javascript中编写异步响应,通过普通回调或使用promises及其关联的.then()
处理程序。并且,该异步结果的所有消费者必须知道它是异步并相应地编程。
此外,承诺是未来价值的代表。您只能使用.then()
处理程序访问它,该处理程序将在(未来某个时间)值准备好或发生错误时被调用。没有同步方法从promise中获取值。
答案 1 :(得分:1)
如果您可以使用ES2016(ES7)功能(通过Babeljs或库),您可以使用async-await。
使用async-await将函数定义为具有异步代码,然后使用await关键字等待异步函数的响应。异步函数需要返回一个promise。 Async-await允许您编写异步代码,就好像它是同步的一样。