如何阻止 javascript 承诺并返回已解决的结果?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29440632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:21:55  来源:igfitidea点击:

How to block for a javascript promise and return the resolved result?

javascriptasynchronouspromisedeferred

提问by Chris Owens

I am obviously misunderstanding something about either the way js promises are resolved or about the semantics of "return."

我显然误解了 js 承诺的解决方式或“返回”的语义。

I am being called by a function that expects me to be synchronous - to return a value. Calculating that value requires some asynchronous code (specifically, the ForEach method on a dstore Collection

我被一个期望我同步的函数调用 - 返回一个值。计算该值需要一些异步代码(特别是dstore 集合上的 ForEach 方法

What I'm trying to accomplish is approximately this, but this does not work in that the function mySynchronousFunction has no return value.

我试图完成的大约是这样,但这不起作用,因为函数 mySynchronousFunction 没有返回值。

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

I understand that JS has to allow for single-threaded implementations, so that it's not cool to block, but there must be some pattern for gluing asynchronous to synchronous code, that I've just missed.

我知道 JS 必须允许单线程实现,所以阻塞并不酷,但必须有一些模式将异步代码粘合到同步代码,我刚刚错过了。

采纳答案by jfriend00

You cannot make a synchronous result out of an asynchronous operation in Javascript. You just cannot do it. If any part of your operation is async, the entire result must be async and you must either use a callback, a promise or some other such mechanism to communicate when the operation is done and the result is ready.

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

If your async operation already returns a promise (which it looks like), then you should just return that from the wrapper function:

如果您的异步操作已经返回了一个承诺(看起来像),那么您应该只从包装器函数中返回它:

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

You may also want to note that a function that operates via side effects is rarely the best design pattern. You may as well pass in the input and have it return the output via the resolved promise and avoid side effects entirely.

您可能还需要注意,通过副作用运行的函数很少是最好的设计模式。您也可以传入输入并让它通过已解决的承诺返回输出并完全避免副作用。

回答by Guffa

No, there is no way to make asynchronous code syncronous. Once you have made an asynchronous call, you have to handle the result asynchronously all the way.

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

JavaScript is single threaded, so if you make a blocking loop that waits for the result, then the code that takes care of the result won't have a chance to run.

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

If you want to return something from an asynchronous function, you have to return a promise that the calling code can use to handle the result asynchronously.

如果你想从异步函数返回一些东西,你必须返回一个承诺,调用代码可以用它来异步处理结果。