循环中的多个异步函数调用

时间:2019-03-14 17:02:59

标签: javascript asynchronous promise jquery-deferred

我有一堆文件要遍历。对于每个文件,根据某些字段值的不同,我可能会或可能不需要发出异步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。不确定为什么会有所作为。

1 个答案:

答案 0 :(得分:0)

尝试为其创建另一个函数,如下所示

    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');
                })
            });
        }
  }