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

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.