【问题标题】:How to execute promise.then in each iteration of loop? Javascript如何在循环的每次迭代中执行promise.then? Javascript
【发布时间】:2021-06-07 03:24:28
【问题描述】:

我在循环中遇到了 Promise 的问题。我在数据库中有 10000 行,我想打印前 1000 行,然后获取 9 个请求来打印其余的。从技术上讲,我想在循环的每次迭代中打印 1000 个结果,为此,我使用 promise 来获取数据,然后创建 1000 行并打印它。

但问题是,首先 JavaScript 的循环会获取 10 个请求,然后一起执行 10 个 .THEN。

我的意思是:

1000 results  (First loop)
2000 results (Second loop) - Append 1000 new rows to last 1000.
3000 results (Third loop) - Append 1000 new rows to last 2000.
....

我得到了什么:

在最后一张图片中,“第一个 for 循环”收到 10 个请求,当循环结束时,.THEN 打印每个 promise 回调 (.THEN)

这是我的代码:

fetchData('ArticulosSearch', inputValues).then(function (data) {
        console.log(data);
        var source = getGridSource(url, datafields, "array", data);
        // Creamos el grid con las primeras 1000 rows obtenidas
        $("#GridAseguradora").createGrid(source, dataColumns, params);

        //Obtenemos el nº de registros que tiene la bbdd para calcular cuantas peticiones debe hacer
        setTimeout(() => {
            fetchData('ArticulosSearchCount', inputValues).then(function (total_rows) {
                console.log("count");
                console.log(total_rows);
                var filt = (total_rows[0].Column1 / 1000) //pagines - peticiones
                console.log(filt);

                // Creamos promesa para añadir posteriormente las filas al grid una vez hayan terminado todas las peticiones
                for (var i = 1; i < filt; i++) {
                    (function (i) {
                        console.log("first for loop");
                        inputValues.offset = (1000 * i)
                        fetchData('ArticulosSearch', inputValues).then(function (data) {  //Obtenemos las 1000 siguientes filas y las añadimos a un array
                            console.log("obtain 1000 results");
                            console.log(data);
                            var rows = new Array();

                            data.forEach(el => {
                                rows.push(generaterow(el))
                            });

                            $("#GridAseguradora").jqxGrid('addrow', null, rows); // Agregamos las filas generadas anteriormente al grid
                            $("#GridAseguradora_contRegTotal").text("Reg. Visibles: " + $("#GridAseguradora").jqxGrid('getrows').length)
                        })
                    })(i);
                }
            })
        }, 100);
    })

我想获取的 Console.logs:

1-first for loop
obtain 1000 results
(append results)

2-first for loop
obtain 1000 results
(append results)

.....

我希望客户看到的是产品是一点一点加载的,而不是剩下的9000个一起加载

【问题讨论】:

    标签: javascript loops asynchronous promise fetch


    【解决方案1】:

    当您运行循环时,您会立即附加 .then() 子句,因此它们会立即得到解决。您实际上希望阻止每个循环迭代,直到 promise 解决,然后继续进行下一个循环并重复。

    您也可以使用 async / await 来做到这一点,但以下是使用 Promise 实现同步循环迭代的方法:

    let promise = Promise.resolve()
    
    for (let i = 0; i < 10; i++) {
      promise = promise.then(() => {
        fetchData('ArticulosSearch', inputValues).then(res => {
           // your logic here
        })
      })
    }
    

    您使用Promise.resolve() 初始化一个新的promise,并在每次循环迭代时继续向其附加then()s。这些.then() 只会在前一个解决后才会执行。

    这将确保事情一个接一个地安排妥当。

    看看这个sn-p,我试图模拟一些需要可变时间来解决的异步操作:

    const outputEl = document.getElementById('output')
    
    const fetchSomethingFromDBAsyncFake = (idx) => new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        outputEl.innerHTML += `
          <br />
          Loaded chunk ${idx}
        `
        resolve()
        clearTimeout(timeout)
      }, 500 + Math.random() * 1750)
    })
    
    let promise = Promise.resolve()
    
    for (let i = 0; i < 10; i++) {
      promise = promise.then(() => fetchSomethingFromDBAsyncFake(i))
    }
    &lt;div id="output"&gt;&lt;/div&gt;

    【讨论】:

    • 非常感谢你!你解决了我的问题
    猜你喜欢
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-24
    • 1970-01-01
    相关资源
    最近更新 更多