【问题标题】:run multiple ajax calls before resolving a promise在解决承诺之前运行多个 ajax 调用
【发布时间】:2017-12-14 20:56:17
【问题描述】:

我有一个函数可以进行 ajax 调用并用结果解决一个承诺。不幸的是,API 将结果限制为 100,我需要使用偏移参数来获取下一个 100,依此类推。在解决承诺之前,如何进行所有需要的 ajax 调用(API 响应提供值的总数,以便我可以确定要进行的调用次数)?

这是我用来获取前 100 个然后解析的函数:

    let currentOffset = 0;
    let totalCount;
    let offsetCount;

 const makeCall = function(camp) {
        return new Promise(function(resolve, reject) {
            api.get(camp, currentOffset, e => {
                totalCount = e.totalCount;
                offsetCount = Math.floor(totalCount / 100)
                let payload = e.payload;
                for (var a in payload) {

                    myArray.push({
                        'id': payload[a].id,
                        'text': payload[a].text,
                        'url': ads[a].url,
                    });
                }
                resolve();
            });
        });
    };

【问题讨论】:

  • 通过多次调用makeCall 来创建多个promise,然后使用Promise.all 创建另一个promise,该promise 会在所有完成后解析。不要自己写逻辑。
  • 假设payload是一个数组,don't use a for…in enumeration!
  • 听起来您不知道确切应该退回多少物品,并且您想根据退回的物品数量来确定?如果您期望更多结果,您可以在第一个承诺中做出新的承诺。 (这可以做成一个函数,以便您创建的所有承诺都可以在仍有项目的情况下进行后续承诺)。缺点是这可能会更慢,因为您需要等到每个完成才能进入下一个
  • @MariosHadjimichael 如果需要两个以上的 API 调用,您能否澄清一下将 Promise 放入 Promise 中的样子

标签: javascript ajax es6-promise


【解决方案1】:

最好的方法是为每个 ajax 调用创建一个 Promise,然后使用Promise.all() 确定所有请求何时成功。

类似于下面的 sn-p。只有在所有调用成功后,此承诺才会解决。请记住,如果任何 ajax 请求失败,它将永远无法解决,因此值得添加一些东西来处理它。

let currentOffset = 0;
let totalCount;
let offsetCount;

const makeCall = function(camp) {
    let apiPromises = [];

    // Repeat the below for each ajax request
    apiPromises.push(
    new Promise(function(resolve, reject) {
        api.get(camp, currentOffset, e => {
            totalCount = e.totalCount;
            offsetCount = Math.floor(totalCount / 100)
            let payload = e.payload;
            for (var a in payload) {

                myArray.push({
                    'id': payload[a].id,
                    'text': payload[a].text,
                    'url': ads[a].url,
                });
            }
            resolve();
        });
    }));

    return Promise.all(apiPromises);
};

【讨论】:

  • 如果我在拨打电话之前不知道总数,我该如何设置一定次数来重复 apiPromises.push
  • 您知道要检索的总结果数吗?似乎这里的问题可能是如何确定何时停止进行 ajax 调用。
  • 总结果在 ajax 响应中给出。响应包括一个对象数组(有效负载)和键总数
  • 这是单个请求的总结果?还是所有请求完成后的总结果?
  • E.totalcount 是所有记录,包括尚未发送的记录
【解决方案2】:

您可以使用第一次调用来确定选项的数量,然后创建所需数量的 ajax 调用以获取其余值以及每个 ajax 调用的相应承诺。在所有其他 ajax 调用完成后,解决第一个承诺。这部分可以通过Promise.all() 完成。

let currentOffset = 0;
let totalCount;
let offsetCount;

const makeCall = function(camp) { 
    // Repeat the below for each ajax request
    return new Promise(function(resolve, reject) {
        let apiPromises = [];

        api.get(camp, currentOffset, e => {
            totalCount = e.totalCount;
            offsetCount = Math.floor(totalCount / 100)
            let payload = e.payload;
            for (var a in payload) {

                myArray.push({
                    'id': payload[a].id,
                    'text': payload[a].text,
                    'url': ads[a].url,
                });
            }

            for (var numCalls = 1; numCalls < offsetCount; numCalls++) {
                // Increment currentOffset here
                apiPromises.push(new Promise(function() {
                    api.get(camp, currentOffset, e => {
                        // Add each value to array
                    }
                }
            }

            Promise.all(apiPromises).then(resolve);
        });
    });
};

有一些细节需要填写,但应该有它的要点。

【讨论】:

    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2021-08-11
    相关资源
    最近更新 更多