【问题标题】:Axios post request not running in sequenceaxios post请求未按顺序运行
【发布时间】:2020-11-15 17:05:15
【问题描述】:

我正在尝试正确使用异步系列,但无法弄清楚我需要如何准确地将数据发送到其中,以便它以与获取数据完全相同的方式推进每个发布请求。

我有一个 excel 文件,我在其中获得多个状态来标记第一列中存在的每个 id。还有一些状态需要删除,删除部分并不难,我能够在不使用异步系列的情况下做到这一点,但为了发布新记录,我需要使用异步系列。要发布的记录位于“标记状态 1”、“标记状态 1 日期”、“标记状态 2”等列下。所以我编写了一个脚本来使用 for 循环获取记录并将它们发送到一个函数,该函数负责为异步系列建模数据。在 markStatusCall 函数内部,如果我放置一个 forEach 循环并运行调用,则状态顺序会出错。它应该类似于“标记状态 1 值”、“标记状态 2 值”等等。

我在这里附上我的代码,请看下面并查看excel文件here

const Excel = require("exceljs");
const axios = require("axios").default;
const https = require("https");
const _async = require("async");

const instance = axios.create({
  httpsAgent: new https.Agent({
    rejectUnauthorized: false,
  }),
});
const returnedId = "5dd7fa20dcfa9600152cc2de";
const deliveredId = "5dd7fa20dcfa9600152cc2d3";
const returnedByVendorId = "5de7c418362e13001212f238";
const returnedToVendor = "5eb2ebfe02987816aad14269";
const atSwyftWarehouse = "5dd7fa20dcfa9600152cc2d8";
const reAttempted = "5e6ea5d87aa7bb6d726b2bbc";
const requestToReattempt = "5ee134230138634c27a6e1da";
const dispatched = "5dd7fa20dcfa9600152cc2e2";
const parcelAssignedDelivery = "5dd7fa20dcfa9600152cc2e3";
const cancelledByVendor = "5de7c418362e13001212f238";
var workbook = new Excel.Workbook();
workbook.xlsx.readFile("./1.xlsx").then(async function () {
  // use workbook

  var worksheet = workbook.getWorksheet("Interim");

  const parcelIds = [];
  const status = [];
  const date = [];
  var data = [];
  var finalData = [];

  for (let i = 2; i <= 10; i++) {
    worksheet.getRow(i).eachCell((cell, index) => {
      if (cell.value !== "") {
        worksheet.getColumn(index).eachCell((colCell, indexing) => {
          if (indexing === 1) {
            if (colCell.value === "Delete Status 1") {
              deleteData(i, cell);
            } else if (colCell.value === "Delete Status 2") {
              deleteData(i, cell);
            } else if (colCell.value === "Delete Status 3") {
              deleteData(i, cell);
            } else if (colCell.value === "Delete Status 4") {
              deleteData(i, cell);
            } else if (colCell.value === "Delete Status 5") {
              deleteData(i, cell);
            } else if (colCell.value === "Mark Status 1") {
              markData(i, index, cell);
            } else if (colCell.value === "Mark Status 2") {
              markData(i, index, cell);
            } else if (colCell.value === "Mark Status 3") {
              markData(i, index, cell);
            } else if (colCell.value === "Mark Status 4") {
              markData(i, index, cell);
            } else if (colCell.value === "Mark Status 5") {
              markData(i, index, cell);
            }
          }
        });
      }
    });
  }
  function markData(i, index, cell) {
    let row = worksheet.getRow(i);
    let date = row.getCell(index + 1).value;
    let parcelId = row.getCell(1).value;
    if (cell.value !== "" && date !== "") {
      let statusId =
        cell.value === "At Swyft Warehouse"
          ? atSwyftWarehouse
          : cell.value === "Dispatched"
          ? dispatched
          : cell.value === "Reattempted"
          ? reAttempted
          : cell.value === "Delivered"
          ? deliveredId
          : cell.value === "Cancelled"
          ? returnedId
          : cell.value === "Request for Reattempt"
          ? requestToReattempt
          : cell.value === "Parcel Assigned"
          ? parcelAssignedDelivery
          : cell.value === "Cancelled by Vendor"
          ? cancelledByVendor
          : deliveredId;
      console.log(parcelId, statusId, date);
      addStatus(parcelId, statusId, date);
    }
  }
  // Need help from here
  function addStatus(parcelId, statusId, date) {
    let values = {
      parcelId: parcelId,
      statusRepositoryId: statusId,
      createdAt: date,
      updatedByScript: true,
    };
    data.push(values);
  }

  finalData.push(() => markStatusCall(data));
  _async.series(finalData, (err, data) => {
    if (err) {
      console.log(err);
    }
  });

  async function markStatusCall(values) {
    console.log(values, "Came here");
    values.forEach((data) => {
       try {
      let response = await instance.post(
        "https://api.myDomain.com:3000/api/ParcelStatuses",
        {
          parcelId: data.parcelId,
          statusRepositoryId: data.statusRepositoryId,
          createdAt: data.createdAt,
          updatedByScript: data.updatedByScript,
        }
      );
      console.log("Updated");
    } catch (err) {
      console.log("here");
      console.error(err);
    }
    })
  }

【问题讨论】:

  • 尝试在 forEach 中使用 promises 而不是 async-await
  • @Amaarshallyaswankar 非常感谢您对代码的一点帮助。我应该使用 promise.all 还是只使用将返回 promise 的简单函数?我想以最好的方式做到这一点,因为将来需要发布的记录可能会增加,我不能真正依赖一个简单的承诺。所以请一点点代码将不胜感激

标签: javascript asynchronous axios async.js exceljs


【解决方案1】:

这样的工作是否可行:

async function markStatusCall(values) {
  console.log(values, "markStatusCall begin");
  
  function loop(values, index) {
    console.log('loop at index', index);
    const data = {
      parcelId: data.parcelId,
      statusRepositoryId: data.statusRepositoryId,
      createdAt: data.createdAt,
      updatedByScript: data.updatedByScript};

    try {
      let response = await instance.post("https://api.myDomain.com:3000/api/ParcelStatuses", data);
      console.log("Updated");
      if (index <= (values.length -1)) {
        loop(index + 1);
      } else {
        return;
      }
    } catch (err) {
      console.log("Error");
      console.error(err);
    }
  }

  await loop(values, 0);
}

这个想法是循环等待每个 POST 请求,然后再移动到 values 数组中的下一项。 (可能是上面代码中的一些拼写错误)。

See this example on codepen

【讨论】:

【解决方案2】:

尝试做这样的事情

  function markStatusCall(values) {
    let promises=[];
    values.forEach((data) => {
         const promise = instance.post(
        "https://api.myDomain.com:3000/api/ParcelStatuses",
        {
          parcelId: data.parcelId,
          statusRepositoryId: data.statusRepositoryId,
          createdAt: data.createdAt,
          updatedByScript: data.updatedByScript,
        });
      return promises.push(promise);
    })
  Promise.all(promises).then(() => { 
   console.log('success') 
   }).catch(error => { 
  console.error(error.message)
  });
 }

这仍然不能确保您的订单,但强烈建议使用 promises 而不是 async-await

仅当所有响应的延迟相同时,响应顺序才会遵循您的顺序

【讨论】:

  • 还是不行。 “标记状态 2”列中的状态先发布,然后发布 4,然后发布 1,然后发布 3。应该像 1、2、3 和 4
  • 然后你可以尝试运行一个普通的for循环并在里面使用await
  • 我在上面的问题中也尝试过。我正在使用 forEach,但它仍然无法按我想要的方式工作。
  • 你试过 for(let i=0........) 正常的 for 循环吗?
  • 我问这个是因为正常的 for 循环在某些方面与 forEach 不同
猜你喜欢
  • 1970-01-01
  • 2016-04-08
  • 1970-01-01
  • 2020-10-26
  • 2021-06-08
  • 1970-01-01
  • 1970-01-01
  • 2020-09-08
  • 2016-10-08
相关资源
最近更新 更多