【问题标题】:How to block process and wait for result on Node.js?如何在 Node.js 上阻止进程并等待结果?
【发布时间】:2018-05-02 00:31:41
【问题描述】:

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

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

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

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 调用之外,所有其他的都应该正常工作(我假设,一些 for,if,变量赋值,没什么特别的)。而且,我不能把所有的东西都放在回调中,因为在 if、for 和 while 之外还有一段代码……

我找到了 wait.for,但它似乎对我不起作用(并且该项目似乎已被放弃,因为上次提交是 2 年前:/)

【问题讨论】:

  • 您能否更具体地说明为什么异步不适用于这种情况?您可以将所有“继续对结果进行操作”代码移动到回调函数中。
  • 在导出函数的末尾(上面编辑的代码示例),我需要返回一个对象“oResult”,它将包含一些从数据库查询结果计算的值,所以,除非我可以把所有一些花哨的异步回调中的 while/for/if 块之外的代码,它不起作用:(
  • 如果有人知道 Node 何时何地决定将一个函数搁置一旁,稍后再返回它会更清楚 :)
  • 不,您不能 - 绝不能 - 阻止进程。只需使用async.whileasync.for
  • 这是个坏主意。节点,是javascript。 Javascript是单线程的。如果您阻止,服务器将被阻止并且将无法使用。这会导致糟糕的表现。

标签: javascript node.js asynchronous synchronous async.js


【解决方案1】:

我知道所要求的内容是针对 Node.js 范式的。那个不应该阻塞等待异步调用的进程,但有时你只需要这样做(想想“重构其他人为另一个平台编写的 5000 行代码,你必须将它移植到节点” - vs--“阻塞进程10ms等待一个可怜的db调用”)。

因此,对于那些愿意为了该死的最后期限和资源限制而反对最佳实践以及如何完成事情的人,也许只是为了好玩,并准备好对抗数百万的愤怒nodejs-async-warriors,欢迎您来到DEASYNC 的世界。

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

如前所述,它干扰了 Node.js 的底层实现真正的进程阻塞。希望对有需要的人有所帮助。

我的搜索让我发现了其他“解决方案”,试图解决在 Node.js 中编写同步调用的问题,但没有一个适合我的情况。也许它会在其他情况下工作,所以在跳到像 DEASYNC 这样的激进措施之前检查它们会很好:

  • Wait.for:github.com/luciotato/waitfor & Wait.for-es6:github.com/luciotato/waitfor-ES6 =>

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

  • 纤维:github.com/laverdet/node-fibers
  • Streamline.js:github.com/Sage/streamlinejs
  • 简单的 ES6 生成器:chrisbuttery.com/articles/synchronous-asynchronous-javascript-with-es6-generators/
  • 著名的Async:github.com/caolan/async

我希望这将用于善而不是恶。

【讨论】:

    【解决方案2】:

    以生成器方式为基础,如今这种简单的模式在许多情况下都可以成为绝佳的解决方案:

    // 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      相关资源
      最近更新 更多