Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
379 views
in Technique[技术] by (71.8m points)

javascript - Waiting for all promises called in a loop to finish

I'm using the axios promise library, but my question applies more generally I think. Right now I'm looping over some data and making a single REST call per iteration.
As each call completes I need to add the return value to an object. At a high level, it looks like this:

var mainObject = {};

myArrayOfData.forEach(function(singleElement){
  myUrl = singleElement.webAddress;
  axios.get(myUrl)
  .then(function(response) {
    mainObject[response.identifier] = response.value;
   });
});

console.log(convertToStringValue(mainObject));

What's happening of course is when I call console.log the mainObject doesn't have any data in it yet, since axios is still reaching out. What's a good way of dealing with this situation?

Axios does have an all method along with a sister spread one, but they appear to be of use if you know ahead of time how many calls you'll be making, whereas in my case I don't know how many loop iterations there will be.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to collect all of your promises in an array and then use Promise.all:

// Example of gathering latest Stack Exchange questions across multiple sites
// Helpers for example
const apiUrl = 'https://api.stackexchange.com/2.2/questions?pagesize=1&order=desc&sort=activity&site=',
    sites = ['stackoverflow', 'ubuntu', 'superuser'],
    myArrayOfData = sites.map(function (site) {
        return {webAddress: apiUrl + site};
    });

function convertToStringValue(obj) {
    return JSON.stringify(obj, null, '');
}

// Original question code
let mainObject = {},
    promises = [];

myArrayOfData.forEach(function (singleElement) {
    const myUrl = singleElement.webAddress;
    promises.push(axios.get(myUrl));
});

Promise.all(promises).then(function (results) {
    results.forEach(function (response) {
        const question = response.data.items[0];
        mainObject[question.question_id] = {
            title: question.title,
            link: question.link
        };
    });

    console.log(convertToStringValue(mainObject));
});
<script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...