javascript 等待异步函数在 Node.js 中返回
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17844450/
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
Wait for an async function to return in Node.js
提问by Golo Roden
Supposed, I have a async function in Node.js, basically something such as:
假设,我在 Node.js 中有一个异步函数,基本上是这样的:
var addAsync = function (first, second, callback) {
setTimeout(function () {
callback(null, first + second);
}, 1 * 1000);
};
Now of course I can call this function in an asynchronous style:
现在我当然可以以异步方式调用这个函数:
addAsync(23, 42, function (err, result) {
console.log(result); // => 65
});
What I am wondering about is whether you can make it somehow to call this function synchronously. For that, I'd like to have a wrapper function sync
, which basically does the following thing:
我想知道的是您是否可以以某种方式同步调用此函数。为此,我想要一个包装函数sync
,它基本上执行以下操作:
var sync = function (fn, params) {
var res,
finished = false;
fn.call(null, params[0], params[1], function (err, result) {
res = result;
finished = true;
});
while (!finished) {}
return res;
};
Then, I'd be able to run addAsync
synchronously, by calling it this way:
然后,我可以addAsync
通过这种方式调用它来同步运行:
var sum = sync(addAsync, [23, 42]);
Note: Of course you wouldn't work using params[0]
and params[1]
in reality, but use the arguments
array accordingly, but I wanted to keep things simple in this example.
注意:当然,您实际上不会使用params[0]
and params[1]
,而是相应地使用arguments
数组,但我想在这个例子中保持简单。
Now, the problem is, that the above code does not work. It just blocks, as the while
loop blocks and does not release the event loop.
现在,问题是,上面的代码不起作用。它只是阻塞,因为while
循环阻塞并且不释放事件循环。
My question is: Is it possible in any way to make this sample run as intended?
我的问题是:是否有可能以任何方式使此示例按预期运行?
I have already experimented with setImmediate
and process.nextTick
and various other things, but non of them helped. Basically, what you'd need was a way to tell Node.js to please pausethe current function, continue running the event loop, and getting back at a later point in time.
我已经尝试过setImmediate
和process.nextTick
以及其他各种事情,但没有一个有帮助。基本上,您需要一种方法来告诉 Node.js 请暂停当前函数,继续运行事件循环,并在稍后的时间点返回。
I know that you can achieve something similar using yield
and generator functions, at least in Node.js 0.11.2 and above. But, I'm curious whether it works even without?
我知道你可以实现类似的 usingyield
和 generator 函数,至少在 Node.js 0.11.2 及更高版本中。但是,我很好奇即使没有它是否有效?
Please note that I am fully aware of how to do asynchronous programming in Node.js, of the event loop and all the related stuff. I am also fully aware that writing code like this is a bad idea, especially in Node.js. And I am also fully aware that an 'active wait' is a stupid idea, as well. So please don't give the advice to learn how to do it asynchronously or something like that. I know that.
请注意,我完全了解如何在 Node.js、事件循环和所有相关内容中进行异步编程。我也完全意识到编写这样的代码是一个坏主意,尤其是在 Node.js 中。而且我也完全意识到“主动等待”也是一个愚蠢的想法。所以请不要给出学习如何异步或类似的建议。我知道。
The reason why I am asking is just out of curiosity and for the wish to learn.
我问的原因只是出于好奇和学习的愿望。
采纳答案by Mike Bild
- You can use npm fibers (C++ AddOn project) & node-sync
- implement a blocking call in C(++) and provide it as a library
- 您可以使用 npm 光纤(C++ 附加项目)和节点同步
- 在 C(++) 中实现阻塞调用并将其作为库提供
Yes I know-you know - BUT EVER-EVER-EVER ;)
是的,我知道 - 你知道 - 但永远永远永远;)
Non-Blocking) use a control flow library
非阻塞)使用控制流库
回答by Lucio M. Tato
I've recently created simpler abstraction WaitForto call async functions in sync mode (based on Fibers). It's at an early stage but works. Please try it: https://github.com/luciotato/waitfor
我最近创建了更简单的抽象WaitFor以在同步模式下调用异步函数(基于 Fibers)。它处于早期阶段,但有效。请尝试:https: //github.com/luciotato/waitfor
using WaitFor your code will be:
使用 WaitFor 您的代码将是:
console.log ( wait.for ( addAsync,23,42 ) ) ;
You can call any standard nodejs async function, as if it were a syncfunction.
您可以调用任何标准的 nodejs 异步函数,就好像它是一个同步函数一样。
wait.for(fn,args...)fulfills the same need as the "sync" function in your example, but inside a Fiber (without blocking node's event loop)
wait.for(fn,args...)满足与示例中的“同步”函数相同的需求,但在 Fiber 内(不阻塞节点的事件循环)
回答by sibidiba
Standard propmises and yield (generator functions) will make this straigthforward:
标准的propmises和yield(生成器函数)将使这变得简单:
http://blog.alexmaccaw.com/how-yield-will-transform-node
http://blog.alexmaccaw.com/how-yield-will-transform-node
http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators
http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators