2

I am trying to synchronously iterate over an array using async.each:

async.each(supplier_array, function(supplier) {
    console.log('looking at : ' + supplier);
    knex(host_name + '.order_item').where({
        supplier: supplier,
        order_id: order_id
    }).then(function(data) {
        console.log(data);
        knex(host_name + '.distributor').select()
        .then(function(data) {
            console.log(data);
        }).catch(function(error) {
            console.log('error: ' + error);
        });
    }).catch(function(error) {
        console.log('error: ' + error);
    });
});

My supplier_array has 3 elements. So what SHOULD happen is the app should (synchronously):

For supplier 1 / first arr / first array element:

  • console.log(supplier)
  • console.log(order_item)
  • console.log(distributor)

For supplier 2 / second array element:

  • console.log(supplier)
  • console.log(order_item)
  • console.log(distributor)

For supplier 3 / third array element:

  • console.log(supplier)
  • console.log(order_item)
  • console.log(distributor)

HOWEVER, it acts asynchronously:

  • console.log(supplier)
  • console.log(supplier)
  • console.log(supplier)

  • console.log(order_item)

  • console.log(order_item)
  • console.log(order_item)

  • console.log(distributor)

  • console.log(distributor)
  • console.log(distributor)

Can someone help me achieve the desired effect of running through the steps inside of async synchronously?

Thanks in advance!

1
  • You might have to do a "return" on each knex promise. That acknowledges the async to let it know that there's a promise to process. Try it, and let me know if it's the right answer. I ran into this issue with knex myself. Also, you can move the inside "then" on line 9 out a level, since you're returning a promise. Commented Mar 23, 2016 at 2:30

1 Answer 1

3

You should use async.eachSeries if you want to iterate them in serial order. Try something like this:

async.eachSeries(supplier_array, function(supplier, callback) {
    console.log('looking at : ' + supplier);
    knex(host_name + '.order_item').where({
        supplier: supplier,
        order_id: order_id
    }).then(function(data) {
        console.log(data);
        knex(host_name + '.distributor').select()
        .then(function(data) {
            console.log(data);
            callback(); // Advance to next iteration here
        }).catch(function(error) {
            console.log('error: ' + error);
            callback(error); // Also callback when error occurs
        });
    }).catch(function(error) {
        console.log('error: ' + error);
        callback(error); // Also callback when error occurs
    });
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks - to confirm - callback() will tell it to look at the next supplier, and apply all those processes to the next supplier?
It seems to work like that. Besides, you should also take care about a common pitfall documented in the README of async.js: github.com/caolan/async#synchronous-iteration-functions

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.