Javascript forEach异步请求是否包含在承诺中?

Javascript forEach异步请求是否包含在承诺中?,javascript,arrays,asynchronous,promise,Javascript,Arrays,Asynchronous,Promise,需要与承诺相关的帮助。请参考下面的细节,主题更具理论性,我不明白我应该使用什么流程: 我们有一个异步函数getDataFromUri(),它返回数据,将数据过滤并保存到对象的arr中,并将其命名为res 对于数组res中的每个活动(对象),我希望发送异步请求,将活动的产品图像存储到对象。因此,我应该有一个数组res,其中存储了所有过滤数据(活动名称、活动图像) 我需要smth,比如: [{ name: "Somename", images: ['uri', 'uri', 'uri', '

需要与承诺相关的帮助。请参考下面的细节,主题更具理论性,我不明白我应该使用什么流程:

  • 我们有一个异步函数getDataFromUri(),它返回数据,将数据过滤并保存到对象的arr中,并将其命名为res
  • 对于数组res中的每个活动(对象),我希望发送异步请求,将活动的产品图像存储到对象。因此,我应该有一个数组res,其中存储了所有过滤数据(活动名称、活动图像) 我需要smth,比如:

    [{
      name: "Somename",
      images: ['uri', 'uri', 'uri', 'uri', 'uri', 'uri']
    },{
      name: "Somename",
      images: ['uri', 'uri', 'uri', 'uri', 'uri', 'uri']
    }
    ]
    
  • 使用RES数组执行其他一些操作
  • 此函数用于获取以下活动:

    function getDataFromUri(uri) {
      return new Promise((resolve, reject) => {
        request.get(uri, (err, res, body) => {
         if(err || res.statusCode !== 200 ) {
           reject(handleErr(err));
         } else {
           resolve(body);
         }
       });
     });
    }
    
    此函数用于获取活动的图像:

    function getProductsOfCampaign(id) {
      var productsImagesLinks = [];
      return new Promise((resolve, reject) => {
        getDataFromUri(`SOME_URI/${id}.json`)
          .then((json) => {
            var productsList = JSON.parse(json).products;
            resolve (productsList.map((product) => product.imgSrc));
          }).catch((e) => {
            throw new Error(e);
          })
      });
    }
    
    在这里我遇到了一个问题:

    getDataFromUri(someLink) //Get campaings;
      .then((result) => {
    
        //NOT WORKING FOREACH
    
        result.forEach((item, i) => {
          item.images = getProductsOfCampaign(item.id);
        })
    
        return result;
        })
      .then((result) => {
        //Do something else to array with images;
      });
    
  • 如何强制forEach.then()表达式后面的next等待保存所有图像URL
  • 我试过Promise.all(),但似乎不知道如何以正确的方式实现它
  • 如果你能帮我解决这个案子,我将不胜感激。谢谢。

    请注意:

  • forEach
    中的
    项是副本
  • getProductsOfCampaign
    返回一个
    承诺
  • 网络是一种尽力而为的服务
  • 这样做:

    getDataFromUri(someLink) // Get campaigns
      .then(result => {
    
        var promises = result.map(item =>
          getProductsOfCampaign(item.id)
            .then(products => {
              item.images = products;
              return item;
            })
            // 3: Best-effort service
            .catch(() => {})
        );
    
        return Promise.all(promises);
      }).then(items => {
    
        console.log(items);
        // Do something else to array of items with images
      });
    

    其他读者可以通过以下方法测试正确性:

    function getDataFromUri(someLink) {
      return new Promise((resolve) => {
        setTimeout(resolve, 1000, [{id: 1}, {id: 2}]);
      })
    }
    
    function getProductsOfCampaign(id) {
      return new Promise((resolve) => {
        setTimeout(resolve, 1000, id * id);
      })
    }
    
    var someLink = '';
    

    感谢Benjamin Grunbaum建议
    .catch(()=>{})
    可以与
    Promise一起使用。所有的
    都可以提供尽力而为的服务。

    不确定它是否重复,但展示了如何执行此操作,无论是串联还是并联。您可以尝试使用,可能会更改一些逻辑。这是因为
    .forEach
    没有返回值,您需要使用
    .map
    ,它可以返回要等待的内容(承诺)。请避免!
    let campaigns = null;
    getDataFromUri(someLink) //Get campaings;
     .then((result) => {
      campaigns = result;
    
      let pImages = []
      result.forEach((item, i) => {
        pImages.push(getProductsOfCampaign(item.id));
      });
    
      return Promise.all(pImages);
     })
     .then((images) => {
       campaigns.forEach((campaign, index) => {
         campaign.images = images[index];
       });
    
       // ... Do something else to array with images;
     });