最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - run multiple ajax calls before resolving a promise - Stack Overflow

programmeradmin2浏览0评论

I have a function that makes an ajax call and resolves a promise with the result. Unfortunately the API limits results to 100 and I need to use an offset parameter to get the next 100 and so on. How can I make all the needed ajax calls (the API response provides the total number of values so I can determine the number of calls to make) before resolving the promise?

Here is function I was using to just get the first 100 and then resolve:

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

I have a function that makes an ajax call and resolves a promise with the result. Unfortunately the API limits results to 100 and I need to use an offset parameter to get the next 100 and so on. How can I make all the needed ajax calls (the API response provides the total number of values so I can determine the number of calls to make) before resolving the promise?

Here is function I was using to just get the first 100 and then resolve:

    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();
            });
        });
    };
Share Improve this question asked Jul 11, 2017 at 0:43 user6363349user6363349 4
  • Make multiple promises from calling makeCall multiple times, then use Promise.all to create another promise that resolves when all are done. Don't write the logic yourself. – Bergi Commented Jul 11, 2017 at 1:00
  • Assuming payload is an array, don't use a for…in enumeration! – Bergi Commented Jul 11, 2017 at 1:01
  • Sounds like you don't know exactly how many items should be returned and you want to determine that based on the number of items returned? You could make a new Promise within the first promise if you expect more results. (this could be made into a function so that all promises you create can make subsequent ones if there are still items). The downside is that this might be slower since you will need to wait until each one is pleted to go onto the next – Marios Hadjimichael Commented Jul 11, 2017 at 1:01
  • @MariosHadjimichael could you clarify what placing the promise within the promise would look like if there are more than two API calls needed – user6363349 Commented Jul 11, 2017 at 2:35
Add a ment  | 

2 Answers 2

Reset to default 2

The best way to do this would be to create a Promise for each of the ajax calls, and then use Promise.all() to determine when all of the requests have succeeded.

Something like the snippet below. This promise will only resolve once all calls succeed. Remember that it will never resolve if any of the ajax requests fail, so it could be worth adding something to handle that.

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

You could use the first call to determine the number of options, then create the needed number of ajax calls to get the rest of the values and a corresponding promise for each ajax call. Resolve the first promise, once all other ajax calls have pleted. That part could be done with 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);
        });
    });
};

There is some details to fill in, but that should have the gist of it.

发布评论

评论列表(0)

  1. 暂无评论