refactor
refactor

Reputation: 15034

looping promises in nodejs

I am learning promises in nodejs, below is my example code. The output of below code is test - 1 test - 2 test - 3 test - 4

var Q = require('q');
var promise = Q.when('test');

promise.then( function(val) {
console.log(val + '-' + '1');
});

promise.then( function(val) {
 console.log(val + '-' + '2');
});

promise.then( function(val) {
 console.log(val + '-' + '3');
});

promise.then( function(val) {
console.log(val + '-' + '4');
});

I would like to know how I can write the same code using for loop.

Upvotes: 0

Views: 199

Answers (4)

jgldev
jgldev

Reputation: 191

First of all, having native promises since ES6, I think that it is not a good idea to use a library unless you have to support old browsers or old nodejs versions.

When you work with promises, you are working with asynchronous code, so, you can loop in different ways.

Imagine you have this snippet:

function step1 (item){
  return new Promise((resolve, reject) => {
    setTimeout(()=>{
      resolve('step 1 for item ' + item);
    }, 1000);
  });
}

function step2 (item){
  return new Promise((resolve, reject) => {
     setTimeout(()=>{
       resolve('step 2 for item ' + item);
     }, 1000);
  });
}

function step3 (item){
  return new Promise((resolve, reject) => {
    setTimeout(()=>{
      resolve('step 3 for item ' + item);
    }, 1000);
  });
}

function processItem (item) {
  return step1(item).then(result =>{
     console.log(result);
     return step2(item);
  }).then(result =>{
     console.log(result);
     return step3(item);
  }).then(result =>{
     console.log(result);
     return ('finished process of item ' + item);
  }).catch(err =>{
     throw (err);
  });
}

where the processItem function will be applied to an items array.

  • A. Run a foor loop.

The code above is asynchronous, so, when you run it, then inmediatly the next one is executed, so, if the processItem function takes 3 seconds to finish, and you want to apply that function to 10 items, it will take 3 seconds because the Promise call will be executed secuentially, but without waiting to finish any of the them.

Example code:

function promiseFor(set, fn){
    return new Promise((resolve, reject) => {
      return arr.map(item => ()=> fn(item)).forEach(proc => {
        return proc().then(res => {
          resolve();
        }).catch(err=>{
          console.log(err);
        });
      });
    });
}
  • B. run the promises in sequence. The sequence not will start to execute any promise until the previous one has been executed, this is like a non asynchronous foor loop: Example:
function sequence (set, fn){
  return set.map(item => ()=> fn(item)).reduce((curr, next)=> {
    return curr.then(()=>{
      return next();
    })},Promise.resolve());
}

Upvotes: -1

refactor
refactor

Reputation: 15034

At last I could do I wanted to , below is the code

var Q = require('q'); 
var promise = Q.when('test');

for(var idx = 1 ; idx <= 4 ; idx++)
{
   (function()
   {
      var temp = idx;
       promise.then( function(val) {
             console.log(val + '-' + temp);
          });

   })();
}

and it works ! I promise :)

Upvotes: 1

Bergi
Bergi

Reputation: 664185

This isn't really specific to promises. If you're creating callbacks in a loop, you'll need an extra closure scope, other than that it's quite standard.

However, the simplest way for your specific case would be to use a single callback only, as they are all attached to the same promise anyway and will receive the same value. So you use

require('q').when('test').then(function(val) {
    for (var i=1; i<=4; i++) {
        console.log(val + '-' + i);
    }
});

Upvotes: 1

oleh.meleshko
oleh.meleshko

Reputation: 4795

From q documentation:

If you want to run a dynamically constructed sequence of functions, you'll want something like this:

var funcs = [foo, bar, baz, qux];

var result = Q(initialVal);
funcs.forEach(function (f) {
    result = result.then(f);
});
return result;

Where initialVal is your Q.when('test').

Upvotes: 0

Related Questions