假设我在Node.js中有一个异步函数,基本上是这样的:
var addAsync = function (first, second, callback) {
setTimeout(function () {
callback(null, first + second);
}, 1 * 1000);
};
现在我当然可以以异步方式调用此函数:
addAsync(23, 42, function (err, result) {
console.log(result); // => 65
});
我想知道的是你是否可以以某种方式同步调用此函数。为此,我想要一个包装函数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;
};
然后,我可以通过这种方式同步运行addAsync
:
var sum = sync(addAsync, [23, 42]);
注意:当然,你不能在现实中使用params[0]
和params[1]
,但是相应地使用arguments
数组,但我想在此保持简单示例的
现在问题是,上面的代码不起作用。它只是阻塞,因为while
循环阻塞并且不释放事件循环。
我的问题是:是否可以以任何方式使该样本按预期运行?
我已经尝试了setImmediate
和process.nextTick
以及其他各种各样的事情,但是他们没有帮助。基本上,您需要的是告诉Node.js 暂停当前函数,继续运行事件循环以及稍后返回的方法。
我知道你可以使用yield
和生成器函数来实现类似的东西,至少在Node.js 0.11.2及更高版本中是这样。但是,我很好奇它是否有效甚至没有?
请注意,我完全了解如何在Node.js,事件循环和所有相关内容中进行异步编程。我也充分意识到编写这样的代码是一个坏主意,尤其是在Node.js.而且我也充分意识到“积极等待”也是一个愚蠢的想法。 所以请不要给出建议,学习如何异步或类似的方式。我知道。
我问的原因只是出于好奇和想要学习。
答案 0 :(得分:12)
我最近创建了更简单的抽象 WaitFor 来在同步模式下调用异步函数(基于Fibers)。它处于早期阶段但有效。请试一试:https://github.com/luciotato/waitfor
使用WaitFor您的代码将是:
console.log ( wait.for ( addAsync,23,42 ) ) ;
您可以调用任何标准nodejs async函数,就像它是 sync 函数一样。
wait.for(fn,args ...)满足与示例中“sync”函数相同的需求,但在光纤内部(没有阻塞节点的事件循环)
答案 1 :(得分:1)
是的我知道 - 你知道 - 但永远都是这样;)
非阻止)使用控制流程库
答案 2 :(得分:0)