如何阻止JavaScript Promise并返回已解决的结果?

54

很明显,我对JavaScript Promise的解析或者"return"语义有些误解。

一个要求我返回值的函数在调用我时期望我是同步的。计算这个值需要一些异步代码(具体来说,是在dstore Collection上执行ForEach方法)。

我的目标大致如下,但这并不起作用,因为函数mySynchronousFunction没有返回值。

function mySynchronousFunction() {
   var accumulator = {};
   var myPromise = doAsynchronousThingThatSideEffectsAccumulator();
   // Now my caller is expecting the value of accumulator.
   myPromise.then(function() {return accumulator;})
}

我理解JS必须允许单线程实现,以避免阻塞,但一定有一些将异步代码与同步代码粘合在一起的模式,我可能只是错过了它们。


这不是关于允许单线程实现的问题 - 所有 实现都必须是单线程的。 - user229044
@meagar那不是真的 - 没有任何东西表明所有实现都是单线程的 - 例如Java中的Rhino。 - Benjamin Gruenbaum
2
无法添加答案,但这对我很有帮助:http://www.tivix.com/blog/making-promises-in-a-synchronous-manner/ - rainabba
1
听起来 await 可以解决这个问题,即 return await myPromise - Alex
2个回答

44

在JavaScript中,你不能从异步操作中得到同步结果。你就是做不到。如果你的操作中有任何一个部分是异步的,那么整个结果必须是异步的,并且你必须使用回调函数、Promise或其他机制来通知操作完成并准备好结果。

如果你的异步操作已经返回了一个Promise(看起来是这样的),那么你应该只需从包装函数中返回它:

function myWrapperFunction() {
   var accumulator = {};
   var myPromise = doAsynchronousThingThatSideEffectsAccumulator(accumulator);
   // Now my caller is expecting the value of accumulator.
   return myPromise.then(function(result) {
       // operate on the accumulator object using the async result
       return accumulator;
   })
}

myWrapperFunction.then(function(accumulator) {
   // write your code here that uses the accumulator result
});

你可能还需要注意,通过副作用操作的函数很少是最佳的设计模式。你可以传入输入并通过已解决的 Promise 返回输出,完全避免副作用。


27

无法将异步代码变为同步。一旦您进行了异步调用,您必须完全以异步方式处理其结果。

JavaScript是单线程的,因此如果您创建一个阻塞循环,等待结果,那么负责处理结果的代码将没有机会运行。

如果您想从异步函数中返回某些内容,则必须返回一个Promise对象,由调用代码以异步方式处理结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接