2

I want to use a callback function in a while loop like this:

do {
    Methodwithcallback(..function () {
        //do something  
    });
}
while ();

function() will not be called, but it is working without a loop.

The Method take some time to execute and i want to repeat the loop after the Method is finished.

Why is the Method being ignored in the loop? I'm using Node.js

5
  • 1
    Is Methodwithcallback asynchronous ? Commented Nov 27, 2017 at 17:58
  • the function is executed asynchronous. Commented Nov 27, 2017 at 18:00
  • what is the condition of the while loop? Can you confirm that the method was ignored (e.g logging inside the callback) Commented Nov 27, 2017 at 18:12
  • It is an infinite loop to check if a file exists. If it does the file should be uploaded and the loop repeats with a counter+1. I can confirm that the method is ignored. Commented Nov 27, 2017 at 18:24
  • Either you wait for the asynchronous method to finish (this eliminates the benefit of asynchronism), or you make your outer scope asynchronous too Commented Nov 28, 2017 at 8:04

2 Answers 2

1

You can't use loops with asynchronous functions like that - the loop wants to execute "now", and the callback executes "later"..

Try with something like this:

function callback() {
    // do whatever else is needed
    methodWithCallback(callback); // start the next one
}

methodWithCallback(callback); // start the first one
Sign up to request clarification or add additional context in comments.

Comments

0

You can use a recursive callback handler that knows when to stop based on a base case, in the below code it executes once for each item in arr. Also you can use async.series() which is a pre-made library to handle this.

const arr = [...items]
let count = 0

const blockingHandler = () => {
    // Keep track of times invoked
    count++

    // Do something

    // If there is another item to execute, then do it
    if (count < arr.length) {
        MethodwithCallback(blockingHandler))
    }
}

MethodwithCallback(blockingHandler)

If you want to use Promises, bluebird has mapSeries() which will serially iterate over a collection with the given async function.

const Promise = require('bluebird')
const arr = [...items]

Promise.mapSeries(arr, i => {
    MethodwithCallback(() => {
        /* 
         * If there was some error handling you could check for an error
         * if there is one, then return a rejected Promise
         * if (err) {
         *   return Promise.reject(err)
         * }
         */

        // do something

        return Promise.resolve()
    })
})
    .then(() => console.log('All Promises Complete'))
    .catch(err => console.log('An error occurred', err))

If MethodwithCallback() can be promisified, then we can shorten this code a little. Promisification is now built into Node as well via util.promisify()

const Promise = require('bluebird')
const asyncMethod = Promise.promisify(MethodwithCallback)
const arr = [...items]

Promise.mapSeries(arr, i => {
    return asyncMethod()
        .then(() => {
            // do something specific for this item
        })
})
  .then(() => {
    // do something when all items done
  })
  .catch(err => {
    // An error occurred during mapSeries
    console.log('An error occurred', err)
  })

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.