4

I want to pass each item into a function that take times. But seems that the JS function is asynchronized. How can I call the function sequentially ? (Pass next item to function after the previous done)

function main() {
    for (var i = 0; i < n ; i++) {
        doSomething(myArray[i]);
    }
}

function doSomething(item) {
    // do something take time
}

My solution is call the function recusively. But I want to know is there a different way to solve this issue ? Thanks.

function main() {
    doSomething(myArray, 0);
}

function doSomething(item, i) {
    // do something take time
    doSomething(myArray, i + 1);
}
6
  • As far as I know, for-cycles and function calls in javascript are synchronous, so it must be something else that's making the function async. Maybe it's something inside the function itself. Commented Jul 7, 2016 at 2:19
  • Sorry for not mention that, my code is running on a node.js server. Is that why the function is async ? Commented Jul 7, 2016 at 2:22
  • 1
    myArray.forEach(doSomething) comes to mind. Commented Jul 7, 2016 at 2:22
  • Functions don't become async just because they're on node.js. What does your function actually do? Asynchronous functions usually have a callback facility or return a promise, so you can use that to coordinate the subsequent call. Commented Jul 7, 2016 at 2:26
  • Hi @nnnnnn, the function do something like http post request, and i have a callback function. My solution is put the doSomething(myArray, i + 1); inside the callback function. Commented Jul 7, 2016 at 2:31

2 Answers 2

6

In JavaScript, as of 2020, the for-loop is async/await aware. You can return a promise and then await that promise inside of the for loop. This causes the loop to execute in a series, even for long running operations.

function randomSleep(ms, seed=10) {
    ms = ms * Math.random() * seed;
    return new Promise((resolve, reject)=>setTimeout(resolve, ms));
} 
async function doSomething(idx) {
  // long running operations
  const outcome = await randomSleep(500);
  return idx;
}   
const arrItems = ['a','b','c','d'];
for(let i=0,len=arrItems.length;i<len;i++) {
  const result = await doSomething(i);
  console.log("result is", result)
}

Read more about async await in for loops and forEach loops here https://zellwk.com/blog/async-await-in-loops/

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

Comments

0

if you want to pass next item to function after the previous done, you can try to use promise, just like this

var Q = require('q'); 
var promise;
main();
function main() {
     promise = doSomethingPromise(0)
    for (var i = 1; i < 10 ; i++) {
        (function (i) {
            promise = promise.then(function (res) {
                return doSomethingPromise(res + ' ' + i)
            });
        })(i)

    }
}

function doSomethingPromise (item) {
   var d = Q.defer();
      d.resolve(doSomething(item));
   return d.promise;
}

function doSomething(item) {
    // do something take time
    console.log('doSomething', item);
    return item;
}

it can make you function to be called by order.

6 Comments

Hi chenkehxx, I've tried your answer. But looks item[1] to item[item.length-1] are stuck in line Q.defer().
can I see your all code?, I don't run my code neither. it is just pseudocode.
HI chenkenhxx, my code is just like what you wrote here.
@Aaron, I have update my code, you can try it again.
Hi chenkehxx, I've tried your modified answer, but the log shows that only the first item is run in the doSomething function.
|

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.