1

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

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

that was my first option just setting the value using the function, that worked fine for small "find" condions but when I tried with more complex operations the I noticed in the flow control didn't wait for execution of the function, that's the reason I decided to try to implement promises
@Pedro didn't wait for the execution of the function? JavaScript (unless you explicitly ask for it) has no notion of preemptive multitasking, simply put - all code runs to completion. If your code did not run to completion - that means you did something asynchronous. If you did - please create a self contained example of that (preferably in a new question). Otherwise, your code might have thrown an exception. Generally, you should not promisify APIs that don't use callbacks anyway.
thanks for the help, I have created another question with my the other scenario I described earlier on, any help would be totally appreciated stackoverflow.com/questions/23613036/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.