How to chain multiple fetch() promises?

前端 未结 7 1500
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-06 17:08

The following code fetches a json list and then does another fetch call for each list item to change their values. The problem is that it’s not done synchronously. “new” is

7条回答
  •  被撕碎了的回忆
    2021-01-06 17:28

    You shouldn't be using forEach here. The best solution is to use Promise.all which waits for an array of promises (fetch is a promise) to all resolve, after which you can process the data.

    Here I've created a dummy fetch function with some sample data to quickly show you how that works.

    const dummyObj = {
      main: [ { id: 1 }, { id: 2 }, { id: 5 } ],
    	other: {
        1: 'data1',
        2: 'data2',
        3: 'data3',
        4: 'data4',
        5: 'data5',
        6: 'data6',
        7: 'data7',
      }  
    }
    
    // The summy function simply returns a subset of the sample
    // data depending on the type and id params after 2 seconds
    // to mimic an API call
    function dummyFetch(type, id) {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(id ? dummyObj[type][id] : dummyObj[type]);
        }, 2000);
      });
    }
    
    // In the first fetch we display the data, just
    // like you did in your example
    dummyFetch('main')
    .then(data => {
      console.log("old", data);
      return data;
    })
    .then(data => {
    
      // Instead of a forEach use Array.map to iterate over the
      // data and create a new fetch for each
      const promises = data.map(o => dummyFetch('other', o.id));
    
      // You can then wait for all promises to be resolved
      Promise.all(promises).then((data) => {
    
        // Here you would iterate over the returned group data
        // (as in your example)
        // I'm just logging the new data as a string
        console.log(JSON.stringify(data));
    
        // And, finally, there's the new log at the end
        console.log("new", data)
      });
    });

    Here's the async/await version:

    const dummyObj = {
      main: [ { id: 1 }, { id: 2 }, { id: 5 } ],
    	other: {
        1: 'data1',
        2: 'data2',
        3: 'data3',
        4: 'data4',
        5: 'data5',
        6: 'data6',
        7: 'data7',
      }  
    }
    
    function dummyFetch(type, id) {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(id ? dummyObj[type][id] : dummyObj[type]);
        }, 2000);
      });
    }
    
    (async () => {
      const oldData = await dummyFetch('main');
      console.log("old", oldData);
      const promises = oldData.map(o => dummyFetch('other', o.id));
      const newData = await Promise.all(promises);
      console.log(JSON.stringify(newData));
      console.log('new', newData);
    })();

提交回复
热议问题