admin管理员组

文章数量:1406312

I have a list of items, which I want to run an async task on each.

I want to synchronize so each element will be processed once the preceding element has pleted. What I've tried so far is:

function processItems(items) {
    var i = 0;
    while(i < items.length) {
      asyncFunc(items[i], function() { i++ }); // asyncFunc takes a callback parameter       
    }
}

However this loops forever (I believe i is out of scope in the callback function).

Is there a better way to achieve this?

I have a list of items, which I want to run an async task on each.

I want to synchronize so each element will be processed once the preceding element has pleted. What I've tried so far is:

function processItems(items) {
    var i = 0;
    while(i < items.length) {
      asyncFunc(items[i], function() { i++ }); // asyncFunc takes a callback parameter       
    }
}

However this loops forever (I believe i is out of scope in the callback function).

Is there a better way to achieve this?

Share Improve this question asked Jul 24, 2014 at 2:12 iosephioseph 1,91721 silver badges26 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

I think the following acplishes what you're looking for:

function processItems(items) {
    var i = 0,
        length = items.length,
        fn = function() {
            if(i < length) {
                asyncFunc(items[i], fn);
                i++;
            }
        };

    fn();
}

fn is a function that sets the callback equal to itself as long as the index is less than the length. Then I call fn once to start it off. Here's a fiddle:

http://jsfiddle/8A8CG/


Alternatively, if asyncFunc returns a promise, you can use Array#reduce to process the items in a series:

function processItems(items) {
  return items.reduce((promise, item) => {
    return promise.then(() => asyncFunc(item));
  }, Promise.resolve());
}

If you need to execute a set of async function in series, I highly remend the async module for node. It offers a series method to execute async tasks in series. It also offers a waterfall method that will pass the results of the previous task to the next task.

Oops. You are looking for eachSeries. Here's how it might work for you:

var async = require('async');

async.eachSeries(items, asyncFunc, function(err){ if(err) return "OH NO"; return "Yay!"})

Make sure asyncFunc invokes a callback with either an error or null.

本文标签: javascriptIterate over array running async task on each elementStack Overflow