2015-04-03 159 views
5

我显然对js承诺解决的方式或“返回”的语义存在误解。如何阻止JavaScript承诺并返回已解决的结果?

我被一个函数调用,期望我是同步的 - 返回一个值。计算该值需要一些异步代码(具体而言,在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必须考虑到单线程的实现,所以它的不冷静阻止,但必须有胶合异步到同步的代码结构,我只是错过了已经。

+0

这不是关于允许单线程实现 - **所有**实现都必须是单线程的。 – meagar 2015-04-03 22:48:21

+0

@meagar这不是真的 - 没有说所有的实现都是单线程的 - 例如Java中的Rhino。 – 2015-04-04 08:18:50

+1

无法添加答案,但这对我有帮助:http://www.tivix.com/blog/making-promises-in-a-synchronous-manner/ – rainabba 2016-06-03 16:01:58

回答

5

你不能从异步操作中取得同步结果在JavaScript中。你不能这样做。如果您的操作的任何部分是异步的,则整个结果必须是异步的,并且您必须使用回调,承诺或其他此类机制在操作完成且结果准备就绪时进行通信。

如果异步操作已返回一个承诺(它看起来像),那么你应该刚刚返回,从包装函数:

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 
}); 

您可能还需要注意的是通过一边进行动作的功能效果很少是最好的设计模式。你也可以通过输入,并通过解决的承诺返回输出,并完全避免副作用。

3

不,没有办法使异步代码同步。一旦进行了异步调用,就必须一直以异步方式处理结果。

JavaScript是单线程的,所以如果你创建一个等待结果的阻塞循环,那么处理结果的代码就没有机会运行。

如果您想从异步函数返回某些内容,则必须返回调用代码可用于异步处理结果的承诺。