【问题标题】:Multiple asynchronous function calls in loop [duplicate]循环中的多个异步函数调用[重复]
【发布时间】:2019-08-05 16:30:41
【问题描述】:

我有一堆文件要迭代。对于每个文件,根据某些字段值,我可能需要也可能不需要进行异步 AJAX 请求以获取其他数据。在所有这些请求都解决之后,我想将该文件的相关数据附加到网页,然后再继续下一个文件。我的实际代码包含无关信息,但逻辑类似于以下伪代码:

var chain = $.when();
for(x = 0; x < files.length; x++) {
    console.log('FOO');
    chain = chain.then(function() {
        var fieldNamePromises = [];
        var fieldName2Promises = [];

        if ('fieldName' in files[x]) {
            //getFieldNameData returns an AJAX request
            fieldNamePromises.push(getFieldNameData())
        }

        if ('fieldName2' in files[x]) {
            //getField2NameData returns an AJAX request
            fieldName2Promises.push(getFieldName2Data())
        }

        Promise.all(fieldNamePromises.concat(fieldName2Promises)).then(function() {
            console.log('BAR');
        })
    });
}

对我来说,这会记录:

'FOO'
'FOO'
'FOO'
'BAR'
'BAR'
'BAR'

而我想要:

'FOO'
'BAR'
'FOO'
'BAR'
'FOO'
'BAR'

如何强制它等待我的所有异步请求完成后再继续我的循环?

以下还产生三个 FOO,后跟三个 BAR,而不是交替产生 FOO BAR。

getFileHistory(fileNumber, function (files) {
    var chain = $.when();
    for (let x = 0; x < files.length; x++) {
        chain = chain.then(function () {
            console.log('FOO');
            var fieldNamePromises = [];

            fieldNamePromises.push(getData('Data', function () { }))


            fieldNamePromises.push(getData('Data', function () { }))


            return Promise.all(fieldNamePromises).then(function () {
                console.log('BAR');
            })
        });
    }
});

function getFileHistory(fileNumber, callback) {
    var url = window.baseUrl + "api/get-file-history/filter?fileNumber=" + fileNumber;
    return $.ajax({
        type: 'GET',
        url: url,
        contentType: 'application/json; charset=utf-8',
        dataType: "json",
        success: function (result) {
            callback(result);
        }
    });
}

function getData(id, callback) {
    var url = "api/" + id;
    return $.ajax({
        type: 'GET',
        url: url,
        contentType: 'application/json; charset=utf-8',
        dataType: "json",
        success: function (result) {
            callback(result);
        },
        error: function (error) {
            console.log(error);
        }
    });
}

更新:当我从 getFileHistory(另一个 AJAX 调用)中删除循环时,它会按预期返回 FOO/BAR。不完全确定为什么会有所作为。

【问题讨论】:

  • 虽然保证了数组顺序,但每个 AJAX 调用可能需要不同的时间才能返回。我建议将它们链接起来,而不是一次全部执行。链如callOne.then(callTwo.then(callThree))
  • 由于每个 AJAX 调用可能需要也可能不需要调用,因此构建这样的链将非常难看,如果可能的话(实际代码要复杂得多)。想知道是否有更清洁的选择。
  • @Dementic 下面的代码仍然返回 'FOO FOO BAR BAR' 而不是 'FOO BAR FOO BAR' - 有什么想法吗? for (x = 0; x
  • 同意这会很丑,但我认为你别无选择。
  • 您的 FOO 被同步记录(在您的 for 循环中)和您的 BAR 异步记录(在以后的事件线程中),保证 FOO, FOO, FOO, BAR, BAR, BAR。对于FOO, BAR, FOO, BAR, FOO, BAR,将console.log(foo) 行移到外部then() 内,同样重要的是,return Promise.all(...).then(...)。没有return,链上不会收到Promise.all(...).then(...)的结算通知。

标签: javascript asynchronous promise jquery-deferred


【解决方案1】:

尝试为它创建一个不同的异步函数,如下所示

    async function(){
         var chain = $.when();
        for(x = 0; x < files.length; x++) {
            console.log('FOO');
            chain = await chain.then(async() => {
                var fieldNamePromises = [];
                var fieldName2Promises = [];

                if ('fieldName' in files[x]) {
                    //getFieldNameData returns an AJAX request
                    fieldNamePromises.push(getFieldNameData())
                }

                if ('fieldName2' in files[x]) {
                    //getField2NameData returns an AJAX request
                    fieldName2Promises.push(getFieldName2Data())
                }

               await Promise.all(fieldNamePromises.concat(fieldName2Promises)).then(function() {
                    console.log('BAR');
                })
            });
        }
  }

【讨论】:

  • 谢谢。我应该提到我做了这个并且它有效。 ...但我需要它才能为 IE 工作,并且不支持 async/await。
  • 不,不要这样做。避免mixing await and .then(…) syntax!如果你想使用async/await,请彻底放弃chain
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 2020-03-07
  • 2018-04-02
相关资源
最近更新 更多