0

I am trying to run a function 4 times (with different parameters) asynchronously with a Promise.all. This snippet runs, however it will only run each 'loopGridValidate' function in order synchronously. I have replaced the loopGridValidate function with the logic from this https://www.javascripttutorial.net/es6/javascript-promise-all/ tutorial and the Promise.all returns what is expected. I'm not sure what I am missing... The loop function is async, everything is set up correctly in the promise all (I have also split out the new promise's into 'const p1 = new Promise' and have the same effect as the code snippet below)

function validateCells() {
        var grid = $("#NonStartUpGrid").data("kendoGrid");
        var rows = grid.tbody.find("tr"); //rows from excel sheet
        var valid = true;
        var errorCount = 0;
        var rowSec1 = Math.floor(rows.length * .25)
        var rowSec2 = Math.floor(rows.length * .5)
        var rowSec3 = Math.floor(rows.length * .75)
        Promise.all([new Promise((resolve, reject) => { resolve(loopGridValidate(rows, grid, errorCount, 0, rowSec1, valid)); })
            , new Promise((resolve, reject) => { resolve(loopGridValidate(rows, grid, errorCount, rowSec1 + 1, rowSec2, valid)); })
            , new Promise((resolve, reject) => { resolve(loopGridValidate(rows, grid, errorCount, rowSec2 + 1, rowSec3, valid)); })
            , new Promise((resolve, reject) => { resolve(loopGridValidate(rows, grid, errorCount, rowSec3 + 1, rows.length - 1, valid)); })
            ]).then(results => { const total = results.reduce((a, b) => a + b, 0) });
        return errorCount;
    };
  
  async function loopGridValidate(rows, grid, errorCount, begin, end, valid) {
        console.log(begin);
        for (var i = begin; i <= end; i++) {
            var rowModel = grid.dataItem(rows[i]);
            if (rowModel) {
                console.log(i);
                var colCells = $(rows[i]).find("td[role=gridcell]");
                for (var j = 0; j < colCells.length; j++) {
                    //custom logic
                }
            }
        }
        scrollToTop(grid)
        if (valid) {
            $("#SubmitGrid").prop("disabled", "");
        }
        $("#loading").prop("hidden", "hidden");
        return errorCount;
    }

Here is a fiddle to show a basic example of what I am talking about that is happening. If you click the button you will see in the console, the functions are ran synchronously, instead of asynchronously(the i values would be mixed up instead of in order) https://jsfiddle.net/tap16fbo/

  • why you need promise for normal functions, there is nothing there for waiting time like that to complete – Raj Kumar Jul 31 '20 at 13:07
  • I want to run 4 instances of that function at the same time asynchronously to cut the validation time of the grid by 1/4. – Austin Areaux Jul 31 '20 at 13:14

1 Answers1

0

Promise body is synchronous, try using setTimeout. For more information

function loop(begin, end, results) {
  setTimeout(() => {
    for (var i = begin; i <= end; i++) {
      console.log(i);
    }
    results();
  }, Math.random() * 1000)
}

function BeginPromise() {
  const p1 = new Promise((resolve, reject) => {
    loop(0, 100, resolve)
  });
  const p2 = new Promise((resolve, reject) => {
    loop(110, 200, resolve)
  });
  const p3 = new Promise((resolve, reject) => {
    loop(210, 300, resolve)
  });
  return Promise.all([p1, p2, p3]).then(() => console.log('done'))
}
Akshay Bande
  • 2,491
  • 2
  • 12
  • 29
Krzysztof Safjanowski
  • 7,292
  • 3
  • 35
  • 47
  • Does this actually run it async or is this just making it randomize which one is ran first? If I switch the loop numbers to higher, you see that it still prints each one in order (the loop itself... counting in the console from 0-100), it just switches the order in which they are ran in. – Austin Areaux Jul 31 '20 at 15:33
  • Every setTimeout makes code asynchronous by putting next execution in event loop. Engine will grap first item in the next iteration. How about web workers? You could delegate every calculation to it - browser will take care for instantiate worker and destroying it - like https://mdn.github.io/simple-web-worker/ – Krzysztof Safjanowski Aug 01 '20 at 11:45