errorMessage
errorMessage

Reputation: 331

Node.js foreach + promise

I want to print arr=[1, 2, 3, 4] like below.

1 101 2 102 3 103 4 104

but result is below.

1 2 3 4 101 102 103 104

my code

var arr = [1, 2, 3, 4];


var promises = [];
arr.forEach(function(elem){
    print(elem)
        .then(addAndPrint)
}
)

function print(elem){
    return new Promise(function(resolve, reject){
        console.log(elem);
        resolve(elem);
    });
}
function addAndPrint(elem){
    console.log(elem + 100);
}

How can I get result I want?

Upvotes: 1

Views: 1125

Answers (3)

hashtabe_0
hashtabe_0

Reputation: 137

.then can only guarantee your addAndPrint(1) method is executed after print(1) method, but can't make print(2) after addAndPrint(1).

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371168

.thens execute asynchronously (similar to setTimeout(.., 0)) (even if the promise resolves immediately), whereas the promise creation function in new Promise((res, rej) => { runs synchronously. So, if you create a bunch of promises synchronously, such as with forEach before the main thread ends, those promises' blocks will all run immediately before any of the thens are reached.

Use await and either reduce or for..of to ensure the iterations run in serial, not in parallel:

var arr = [1, 2, 3, 4];


var promises = [];
arr.reduce(async function(lastPromise, elem) {
  await lastPromise;
  return print(elem)
    .then(addAndPrint)
}, Promise.resolve())

function print(elem) {
  return new Promise(function(resolve, reject) {
    console.log(elem);
    resolve(elem);
  });
}

function addAndPrint(elem) {
  console.log(elem + 100);
}

Upvotes: 1

Trott
Trott

Reputation: 70163

I'm not sure what constraints you're working with but the choice to use Promises could use some explanation. Because the easiest solution is probably to not use Promises. Promises are good for asynchronous operations, but everything here is synchronous.

var arr = [1, 2, 3, 4];

arr.forEach(function(elem){
  print(elem)
  addAndPrint(elem);
});

function print(elem){
  console.log(elem);
}
function addAndPrint(elem){
  console.log(elem + 100);
}

Upvotes: 1

Related Questions