如何在Node.js上阻塞进程并等待结果

How to block process and wait for result on Node.js?

本文关键字:进程 等待 结果 Node js      更新时间:2023-09-26

我正面临Node.js (v0.12.7)的问题。我正在编写一个应用程序,必须在某个地方停止,等待从查询到数据库的结果,然后它正在做什么。

这个问题不像使用async(系列等)那么简单。我有多个函数和模块相互调用。我尝试使用async,但它没有解决我的问题。

具体来说,我有一个类似这样的方案:

db = require('db-utils');
exports.myFunction() {
    // some code ...
    while(condition) {
        for(i from 0 to x) {
            // code ...
            if(condition) {
                // code ...
                db.executeCall(callback); // async with callback
                // this where I want to stop waiting for result
                // continue doing something with the result, in my case it is jumping, 
                // so I have a result = undefined 
                // code ..
            }
            // code ...
         }
         // code ...
     }
     // code ...
    // calculating some properties of oResult from the db query result above
    return oResult;
}

理想的情况是将文件的所有内容作为顺序代码执行,但除了db调用之外,所有其他内容都应该正常工作(我假设,其中一些用于变量赋值,没有什么花哨的)。而且,我不能把所有的东西都放在回调中,因为在if, for和while之外有一个代码…

我找到了等待。对于,但它似乎对我不起作用(并且该项目似乎被放弃了,因为最后一次提交是2年前:/)

我知道被问到的是反对Node.js范式的。不应该阻塞等待异步调用的进程,但有时你必须这样做(想想"重构其他人为另一个平台编写的5000行代码,你必须将其移植到节点上"——vs——"阻塞进程10ms等待一个可怜的db调用")。

因此,对于那些为了该死的最后期限和资源限制而愿意违背最佳实践和做事方式的人,也许只是为了好玩,并且准备好对抗数百万nodejs-async战士的愤怒,欢迎您来到DEASYNC的世界。

deasync将异步函数转换为同步,通过在JavaScript层调用Node.js事件循环来实现阻塞机制。deasync的核心是用c++编写的。

如前所述,它干扰了Node.js的底层以实现真正的进程阻塞。我希望这将帮助那些需要它的人。

我的搜索让我发现了其他的"解决方案",试图解决在Node.js中编写同步调用的问题,但没有一个适合我的情况。也许它会在其他情况下工作,所以在跳到像DEASYNC:

这样的激进措施之前检查它们将是很好的。
  • 等。for: github.com/luciotato/waitfor &等。for-es6: github.com/luciotato/waitfor-ES6 =>

node.js和浏览器的顺序编程,回调地狱结束。简单、直接的抽象。通过使用wait。for,你可以在顺序/同步模式下调用任何nodejs标准异步函数,等待结果数据,而不会阻塞节点的事件循环。

    <
  • 纤维/strong>: github.com/laverdet/node-fibers
  • Streamline.js : github.com/Sage/streamlinejs
  • Simple ES6 Generators: chrisbuttery.com/articles/synchronous-asynchronous-javascript-with-es6-generators/
  • 著名的Async: github.com/caolan/async

我希望这句话能被用来做好事,而不是做坏事。

基于生成器的方式,现在这个简单的模式在许多情况下都是极好的解决方案:

// 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? ', r=>main.next(r))    
  // and again, in a sync fashion
  var answerB = yield rl.question('are you sure? ', r=>main.next(r))        
  // 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