Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluebird promises - each function

Thank in advance for the help.

While using Bluebird promises, I have a series of promises running. During the last promise, I want to run one function multiple times for each object in an array.

Below there is the pseudocode:

var userArray = [ 
    {
        name: "John",
        email: "[email protected]"

    },
    {
        name: "Jane",
        email: "[email protected]"
    }]; 

var functionOne = function() {
    //returns Promsie object
};

var functionTwo = function() {
    //returns promise object
};

var createUser = function(user) {
    return User.findOrCreate({email: user.email},{
        name: user.name,
        email: user.email
    });
};

functionOne()
    .then(functionTwo)
    .each(createUser(userArray))
    .then(function onComplete() {
        console.log("Complete");
    })
    .catch(function onError() {
        console.log("Um...it's not working");
    });

I know I'm not using the each function correctly. What's the correct way to implement this using Bluebird?

like image 604
Jay Avatar asked Jul 31 '15 12:07

Jay


People also ask

Why do we use Bluebird promises?

The strongest feature of Bluebird is that it allows you to “promisify” other Node modules in order to use them asynchronously. Promisify is a concept applied to callback functions. This concept is used to ensure that every callback function which is called returns some value.

What is promise each?

each. Given an Iterable (an array, for example), or a promise of an Iterable , iterates serially over all the values in it, executing the given iterator on each element. If an element is a promise, the iterator will wait for it before proceeding.

What does promise Promisify do?

promisify. Returns a function that will wrap the given nodeFunction . Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function.

How does promise all work?

Promise.all() The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will fulfill when all of the input's promises have fulfilled, or if the input iterable contains no promises.


3 Answers

As I understand you want to take some asynchronous actions for elements from array. Then please check the following example:

var Promise = require('bluebird');

function createUsersFromArray(userArray){
    return Promise.each(userArray, function(signleUser){
        return createUserFunction(signleUser);
    });
}

or

return Promise.each(userArray, createUserFunction);

functionOne()
  .then(functionTwo)
  .then(function(){
      return createUsersFromArray(userArray);
  })
//or just .then(createUsersFromArray) if functionTwo return this array
  .then(function(createdUsers){
      //here you may retrieve users and make some magic with them
      console.log(createdUsers);
  })
  .then(function onComplete() {
      console.log("Complete");
  })
  .catch(function onError() {
      console.log("Um...it's not working");
  });

I also recommend using "all" instead of "each"

Check the examples below:

return Promise.all(userArray.map(function(singleUser){
    return doSomethingWithUser(singleUser);
}));

or

return Promise.all(userArray.map(doSomethingWithUser));

'all' will notify you if all the actions are taken correctly.

How to use promises (best practice):

http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html https://blog.domenic.me/youre-missing-the-point-of-promises/

like image 190
Roman Sachenko Avatar answered Sep 25 '22 02:09

Roman Sachenko


The most straightforward implementation:

functionOne()
    .then(functionTwo)
    .then(function(){
      return bluebird.each(userArray, createUser);
    })
    .then(function onComplete() {
        console.log("Complete");
    })
    .catch(function onError() {
        console.log("Um...it's not working");
    });

You should use .map instead of .each if you want to access the results of all of those creates.

like image 43
Yuri Zarubin Avatar answered Sep 23 '22 02:09

Yuri Zarubin


Thanks @Roman @Yuri for the help! My now working code is below:

var userArray = [ 
{
    name: "John",
    email: "[email protected]"

},
{
    name: "Jane",
    email: "[email protected]"
}]; 

var functionOne = function() {
    //returns Promise object
};

var functionTwo = function() {
    //returns Promise object
};

var createUser = function(singleUser) {
  //returns Promise object containing creating User
};

functionOne()
    .then(functionTwo)
    .then(function() {
      return Promise.map(userArray, createUser);
    })
    .then(function onComplete(response) {
        console.log("Complete:" + JSON.stringify(response));
    })
    .catch(function onError() {
        console.log("Um...it's not working");
    });
like image 28
Jay Avatar answered Sep 23 '22 02:09

Jay