Node.js 异步同步
Posted
技术标签:
【中文标题】Node.js 异步同步【英文标题】:Node.js async to sync 【发布时间】:2013-05-11 07:11:12 【问题描述】:我怎样才能做到这一点
var asyncToSync = syncFunc();
function syncFunc()
var sync = true;
var data = null;
query(params, function(result)
data = result;
sync = false;
);
while(sync)
return data;
我试图从异步一中获取同步功能, 我需要它来使用 FreeTds 异步查询作为同步查询
【问题讨论】:
异步回调始终在函数堆栈清除后运行。因此,不可能同步返回 ansyc 结果。任何启动异步操作的同步函数都必须在异步操作开始之前返回。 相反,您想让外部函数也异步,方法是让它接受一个在query
的回调内部调用的回调。
查询函数是否执行数据库调用?如果是这样,DB 客户端可能会提供该查询功能的同步版本。
重复:How to block on asynchronous functions in javascript(但没有多少好的解释性答案)
【参考方案1】:
如今,这种生成器模式在许多情况下都可以成为出色的解决方案:
// nodejs script doing sequential prompts using async readline.question function
var main = (function* ()
// just import and initialize 'readline' in nodejs
var r = require('readline')
var rl = r.createInterface(input: process.stdin, output: process.stdout )
// magic here, the callback is the iterator.next
var answerA = yield rl.question('do you want this? ', res=>main.next(res))
// and again, in a sync fashion
var answerB = yield rl.question('are you sure? ', res=>main.next(res))
// readline boilerplate
rl.close()
console.log(answerA, answerB)
)() // <-- executed: iterator created from generator
main.next() // kick off the iterator,
// runs until the first 'yield', including rightmost code
// and waits until another main.next() happens
【讨论】:
这在主函数之外仍然是异步的,如果你把console.log("EOF")
放在最后一行,你会立即看到do you want this? EOF
。这实际上是一个手工制作的async/await
实现【参考方案2】:
使用deasync - 一个用 C++ 编写的模块,它将 Node.js 事件循环暴露给 JavaScript。该模块还公开了一个sleep
函数,该函数会阻塞后续代码,但不会阻塞整个线程,也不会导致忙等待。您可以将sleep
函数放入您的while
循环中:
var asyncToSync = syncFunc();
function syncFunc()
var sync = true;
var data = null;
query(params, function(result)
data = result;
sync = false;
);
while(sync) require('deasync').sleep(100);
return data;
【讨论】:
这是唯一一个你不必在 Fiber 中运行的(如果你不控制调用代码,你就不能总是这样做) 确实!这是唯一一个适用于我的案例。谢谢!【参考方案3】:您遇到的问题是您的紧的 while 循环被阻塞了。所以我认为您的查询回调永远不会运行。我认为您需要使用 setTimeout 等来防止函数阻塞,但如果您这样做,函数将在调用回调之前返回。此功能必须在较低级别实现。
如果您在浏览器中,您可以查看this article。在节点中,您必须依赖于您查询的任何内容的实现。它可能提供也可能不提供同步方法。
【讨论】:
【参考方案4】:我一直在使用syncrhonize.js 并取得了巨大的成功。甚至还有一个挂起的拉取请求(效果很好)来支持具有多个参数的异步函数。比 node-sync imho 更好也更容易使用。额外的好处是它具有易于理解和详尽的文档,而 node-sync 没有。
【讨论】:
【参考方案5】:你可以用node-sync lib做到这一点
var sync = require('sync');
sync(function()
var result = query.sync(query, params);
// result can be used immediately
)
注意:您的查询必须使用标准回调调用(首先出现错误):回调(错误,结果)。 如果您无法更改查询方法,只需创建 .async() 包装器(参见 github 链接)。
【讨论】:
我有带有回调错误和结果的异步函数,“sync(function())”是否能够在正常的 js 同步函数中返回值? 没有。 sync() 只是新的线程上下文。它不返回任何东西。只需用它包装所有代码,您就可以在异步函数上使用 .sync。以上是关于Node.js 异步同步的主要内容,如果未能解决你的问题,请参考以下文章