在 node.js 中承诺一个递归函数

Posted

技术标签:

【中文标题】在 node.js 中承诺一个递归函数【英文标题】:Promisify a recursive function in node.js 【发布时间】:2014-06-30 00:19:31 【问题描述】:

我在我的应用程序中使用bluebird 作为控制流,我正在尝试实现 promisify 以将我的递归函数扩展为一个 Promise,但它似乎是“then”方法从未被处决

我正在做从一个 JSON 对象到另一个对象的映射,find 函数递归地查看 JSON 属性并根据特定条件返回该属性。

var promise = require("bluebird");
var mapToModel = function(res)
  // res is a json structure
  var processes = res.definitions.process;
  var diagrams = res.definitions.BPMNDiagram; 
  var documents = [];
  for(var prop in processes) 
    if(processes.hasOwnProperty(prop))
      var propertyNames = Object.getOwnPropertyNames(processes[prop]);
      for(var property in processes[prop])
        var mapping =;
        if(property==="$")
          //do something with the process
        else
        //shapes
          mapping.hash = hash.hashCode(new Date().toString());
          mapping.type = property;
          mapping.value = processes[prop][property];
            var bpmnItem = findPromise(processes[prop][property], function(x) return x.$.id;).then(function(value)
              //I'm not reaching this point
              var bpmnId = value.$.id;
              console.log(value);
              if(bpmnId!=undefined)
                console.log("return:"+ bpmnId);
                
          );

          documents.push(mapping);
        
      
    
     return documents;
  


var findPromise = promise.promisify(find);
function find(items,f) 
    for(var key in items)  
        var elem = items[key]; 
        if (f(elem))  return elem;
        if(typeof elem === "object")  
            find(elem,f); // call recursively
        
    

【问题讨论】:

【参考方案1】:

Bluebird promisify 方法适用于 NodeJS 的公认回调约定 - nodebacks。

Nodeback 采用 someOp(function(err,result) 的特定格式,即 - 第一个参数始终是错误。

事实上,你的find 方法甚至不是异步的,所以没有理由一开始就承诺它。您可以按原样简单地调用它。

一般来说,你不应该承诺同步函数,你只要正常调用它们。事实上,您的代码中似乎没有任何异步操作 - 所以您根本不应该在其中使用 Promise。

你可以这样做:

mapping.value = processes[prop][property];
var value = find(processes[prop][property], function(x) return x.$.id;);
var bpmnId = value.$.id;
console.log(value);
if(bpmnId!=undefined)
    console.log("return:"+ bpmnId);
  

请记住,Promise 是对最终结果的抽象。就像以前一样,您将继续同步进行所有操作。

【讨论】:

这是我的第一个选项,只是使用该函数设置值,这对于小的“查找”条件工作正常,但是当我尝试使用更复杂的操作时,我注意到流控制中没有等待函数的执行,这就是我决定尝试实现承诺的原因 @Pedro 没有等待函数的执行? javascript(除非你明确要求它)没有抢占式多任务的概念,简单地说 - 所有代码都运行完成。如果你的代码没有运行完成——这意味着你做了一些异步的事情。如果你这样做了 - 请创建一个自包含的 that 示例(最好在一个新问题中)。否则,您的代码可能会引发异常。一般来说,你不应该承诺不使用回调的 API。 感谢您的帮助,我已经用我之前描述的其他场景创建了另一个问题,任何帮助将不胜感激***.com/questions/23613036/…

以上是关于在 node.js 中承诺一个递归函数的主要内容,如果未能解决你的问题,请参考以下文章

Node.js / Javascript 多重递归承诺在视图中返回

对调用承诺返回函数的递归方法进行单元测试

函数递归和承诺

NodeJs分页,递归承诺问题

等待递归 readdir 函数结束

如何使用 Promise Kit 调用递归函数?