2

I vary new for javascript world, I've a simple method like this

function foo(items) {
 var result = []
 // Assume under forEach statement take 2 sec per loop
 items.forEach(function(item) {
     setTimeout(function() {
         result.push(item + 2)
     }, 2000)
  }) 
  return result
}

console.log(foo([1,2,3,4]))
console.log("Done")

Result:

[]
Done

Except output:

[ 3, 4, 5, 6 ]
Done

anyone can help me, Or explain me about asynchronous in javascript to resolve this problem.

6LYTH3
  • 1,426
  • 1
  • 10
  • 9
  • It's because of the `setTimeout`. You're putting asynchronous code inside of a a synchronous loop. Can you get rid of the timeout? – Max Baldwin May 16 '18 at 15:42
  • Why do you need `setTimeout`? If you do need it check the linked question. It provides you with a detailed explanations on how you could handle async in javascript. – Yury Tarabanko May 16 '18 at 15:44
  • @YuryTarabanko @MaxBaldwin actually, In the loop take some time before `push` item into result, it example for query or something that take time. – 6LYTH3 May 16 '18 at 15:49
  • @6LYTH3 Then you do need to check the linked question :) – Yury Tarabanko May 16 '18 at 15:51

3 Answers3

1

Get rid of the setTimeout and it should work as you expect:

function foo(items) {
 var result = []
 // Assume under forEach statement take 2 sec per loop
 items.forEach(function(item) {
     result.push(item+2)
  }) 
  return result
}

console.log(foo([1,2,3,4]))
console.log("Done")

Returns [3, 4, 5, 6]

Vincent Nguyen
  • 1,555
  • 4
  • 18
  • 33
1

Try following

function foo(items) {
 var result = []
 // Assume under forEach statement take 2 sec per loop
 items.forEach(function(item) {
    // Create a promise for each async function
    var promise = new Promise(function(resolve, reject) {
       setTimeout(function() {
           resolve(item + 2); // resolve the async function
       }, 2000);
     });
     result.push(promise); // push the promise into array
  }); 
  // Create one promise for all the promises and return
  return Promise.all(result) 
}
// Now, foo function returns a promise and then is called once the promise is resolved which contains the data
foo([1,2,3,4]).then((response) => console.log(response)).then(() => console.log("Done"));

As setTimeout is an ansync function i.e. it executes out of order, hence, as expected the output was an empty array (when the array was returned, no callback of setTimeout function was executed). You can use Promises for working with async function.

Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
-1

Code :

Uses Array.map to push elements in :

function foo(items) {
 var result = []
 items.map(_=>result.push(_+2))
  return result
}

Explanation :

function foo(items) { // start function
    var result = [] // the result array
 items.map(_=>result.push(_+2)) // map over array and for every element set it equal to that element + 2
  return result; // return resultant array
} // end function

Alternate and better :

foo = items => items.map(_=>_+2)
console.log(foo([1,2,3,4,5]))
Muhammad Salman
  • 433
  • 6
  • 18