Question

I'm using bluebird for the control flow in my application, I'm trying to implement promisify to extend my recursive function into a promise, but it seems like the "then" method never got executed

I'm doing a mapping from one JSON object to another, the find function looks recursively into the JSON properties and returns the property based on an specific condition.

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
        }
    }
}
Was it helpful?

Solution

The Bluebird promisify method works on the accepted callback convention for NodeJS - nodebacks.

Nodebacks are in the specific format of someOp(function(err,result){ that is - the first argument is always an error.

In fact, your find method is not even asynchronous, so there is no reason to promisify it to begin with. You can simply call it as it is.

Generally, you should not promisify synchronous functions, you just call them normally. In fact, you don't seem to have any asynchronous operation in your code - so you should not be using promises at all in it.

You can simply do:

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);
}  

Remember, Promises are an abstraction over an eventual result. You keep doing everything synchronous just like you did before.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top