0

I'm trying to run multiple checks through the for-loop. Sometimes within the loop I have to run an AJAX-request. To check if that is finished I'm using the waitForIt function.

After the for-loop is finished. I want to run the InitAndSeachItems function. But the function always runs while the loop is still running.

I have tried await and a variation of the waitForIt function, but i can not get it to work async. I want to stay away from using sleep, since that is not clean coding. Can someone give me some advice please?

See the codeblock for the function I am running. var bool is set to false after the AJAX-call is finished in another function and works fine. The focus here is about running the initAndSeachItems function at the correct timing.

    this.setFavorietFromJsonString = async function(filterJson) {
    /** set variables */
    filterJson = JSON.parse(filterJson);        /** loop through keys of json object */
    for (var key in filterJson) {
        /** set variables */
        var selectedValues = filterJson[key];

        /** loop through values of the keys */
        Object.keys(selectedValues).forEach(await function(index) {
            /** give input checked true */
            if($('.'+key+'Items#'+selectedValues[index]).length > 0) {
                $('.'+key+'Items#'+selectedValues[index]).prop('checked', true);
            } else {
                bool = true;
                $('#'+key+'Lijst').val(selectedValues[index].replace('-', ' '));
                window["groteFilterSearch"+key](true);
                waitForIt(key, selectedValues[index]);
                async function waitForIt(key, value){
                    if (bool === true) {
                        setTimeout(function(){waitForIt(key, value)},100);
                    } else {
                        setTimeout(function(){
                            $('.'+key+'Items#'+value).prop('checked', true);
                            bool = false;
                        },200);
                    };
                }
            }
        });
    }

    /** set init of listing */
    initAndSearchItems();
};
  • What is `waitForIt()`? *edit* oh, I see. Don't declare functions inside conditional blocks like that; it's not allowed in strict mode and it is not implemented uniformly. – Pointy Oct 01 '20 at 14:15
  • 2
    `.forEach()` doesn't care about `await` – Andreas Oct 01 '20 at 14:16
  • 1
    instead of using forEach use map to return an array of promise then you can wait for it to finish with Promise.all – Chris Li Oct 01 '20 at 14:18
  • You wrote: "But the function always runs while the loop is still running." Do you mean "But the function always runs while not all async calls within the loop have returned their results" ?. – www.admiraalit.nl Oct 01 '20 at 14:18
  • @ChrisLi, yes, this is a very good solution. Could you please enter this as an "Answer" instead of a comment? – www.admiraalit.nl Oct 01 '20 at 14:20
  • You cannot use `forEach` with asynchronous calls. Instead you have to work with a for loop. Check this answer: https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop – FelHa Oct 01 '20 at 14:26
  • Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – Heretic Monkey Oct 01 '20 at 14:30
  • when/where does this variable `bool = true;` ever change back to `false`? Or in other terms, what is `waitForIt` waiting for? – Thomas Oct 01 '20 at 14:41

1 Answers1

1

This stems from the fact that the foreach loop does not honor the await clause, it just keeps iterating. You can use a for...of loop which should honor the await but has the downside that every call waits for the previous to finish. To make the ajax calls in parallel you can use await Promise.all() see Any difference between await Promise.all() and multiple await?

Possible duplicate of: Using async/await with a forEach loop

sebastian.do
  • 120
  • 2
  • 10