【问题标题】:Run a function after Array.map在 Array.map 之后运行一个函数
【发布时间】:2020-08-18 06:00:20
【问题描述】:

我想在 Array.map 完成执行后运行一个异步函数。

我在函数 updateMaterials 的 map 方法中进行异步调用,我的目标是在 updateMaterials 完成执行后调用 addDataToDB。

功能 1:更新材料

 const updateMaterials = recipeRawMaterials => {
    recipeRawMaterials.map((item, index) => {
      updateRawMaterialsDB(item._id, item.rate, index);
    });
  };

异步函数:updateRawMaterialsDB

const updateRawMaterialsDB = async (id, rate, index) => {
    console.log(state.recipeRawMaterials);
    const body = JSON.stringify({
      rate
    });

    console.log(body);

    const config = {
      headers: {
        'Content-Type': 'application/JSON'
      }
    };

    const res = await axios.put(`/api/v1/rawMaterial/${id}`, body, config);

   
  };
 const addDataToDB = async (recipeName, recipeRawMaterials) => {
   

    const config = {
      headers: {
        'Content-Type': 'application/JSON'
      }
    };

    const res = await axios.post('/api/v1/basicRecipe', body, config);
    setLoading();
    
  };

【问题讨论】:

    标签: javascript arrays async-await


    【解决方案1】:

    你可以在 map 中返回 Promise,在 Promise.all 完成后你可以调用 addDataToDB 函数

    const updateMaterials = recipeRawMaterials => {
       const promises =  recipeRawMaterials.map((item, index) => updateRawMaterialsDB(item._id, item.rate, index));
       Promise.all(promises).then(()=>{
           // addDataToDB 
       })
       .catch(e=>{
           //
       })
      };
    

    【讨论】:

      【解决方案2】:

      更常见的方法是使用@Ubeyt Demir 的答案,将异步调用收集到一组承诺中,然后在这些承诺得到解决时触发最终调用。

      此答案使用 ES2018 中的一个功能,您可以在其中使用异步迭代器。这个 ECMA 提案 https://2ality.com/2016/10/asynchronous-iteration.html

      很好地阐述了这一点

      所以使用;

      for await (const asyncItem of asyncCollection) {
        console.log(asyncItem);
      }
      console.log("done")
      

      当异步承诺的迭代器已经解决时,我们将打印“完成”语句。 在您的代码中使用它会如下所示:

      items = [{_id: 1, rate: 2, index: 0},
      {_id: 2, rate: 3, index: 2}, 
      {_id: 3, rate: 4, index: 3}, 
      {_id: 4, rate: 5, index: 4}, 
      {_id: 5, rate: 6, index: 5},]
      
      function sleep(ms) {
          return new Promise(resolve => setTimeout(resolve, ms));
      }
      const updateRawMaterialsDB = async (id, rate, index) => {
          const body = JSON.stringify({
              rate
          });
          console.log(body);
          const config = {
              headers: {
                  'Content-Type': 'application/JSON'
              }
          };
          //return axios.put(`/api/v1/rawMaterial/${id}`, body, config);
          return sleep(2000);
      };
      async function addDataToDB(recipeName, recipeRawMaterials) {
          const config = {
              headers: {
                  'Content-Type': 'application/JSON'
              }
          };
          //const res = await axios.post('/api/v1/basicRecipe', body, config);
          //setLoading();
          console.log('All done');
      };
      
      async function updateMaterials(recipeRawMaterials) {
          const arrayofPromises = recipeRawMaterials.map((item, index) => {
              updateRawMaterialsDB(item._id, item.rate, index);
          });
          for await (const item of arrayofPromises) {
              console.log("item done");
          }
          addDataToDB('something', recipeRawMaterials)
      }
      updateMaterials(items);
      

      【讨论】:

      • 这很时尚! :)
      【解决方案3】:

      与其等待每个Promise 完成,不如将recipeRawMaterials 转换为promise 数组,然后将其传递给Promise.allPromise.all 接受Promises 数组并返回一个。

      const updateMaterials = async recipeRawMaterials => await Promise.all(
        recipeRawMaterials.map(({ _id, rate }, index) => updateRawMaterialsDB(_id, rate, index))
      );
      

      【讨论】:

      • 嗨 Rafi ..感谢您的反馈..一旦承诺得到解决,我如何调用 AddDataToDB 函数..
      • 查看您的代码,updateMaterials 似乎没有返回任何值
      • 我只是在 updateMaterials 中发出一个 API 请求,这会对 promise.all 的实现产生影响..
      • 不,没关系(我以为你需要下次通话的结果)
      • 只需在上述代码正下方调用addDataToDB ,如下:await addDataToDB (...)
      猜你喜欢
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      相关资源
      最近更新 更多