【问题标题】:Chaining API requests with Axios in Node.js in a loop - doesn't work in order在循环中使用 Node.js 中的 Axios 链接 API 请求 - 无法按顺序工作
【发布时间】:2020-12-09 18:28:46
【问题描述】:

编辑: 尝试了下面的建议以及更多的东西,现在这是代码,我几乎只是让它全部异步等待而不是然后捕获......

makeNextAccount();
  

  console.log("Making :" + merchantsToCreate.length + " Accounts")

async function makeNextAccount(currentIndex) {
    for (const item of merchantsToCreate) {

try{
    let accId = "";
    
    var createAccBody = JSON.stringify(
        {
        "email":emails[item],
        "firstName":"sdd",
        "lastName":"dgdg"
    });
    
    
    var createAcc = {
      method: 'post',
      url: url1,
      headers: awsHeaders,
      data : createAccBody
    };

    const createdAccResult = await axios(createAcc); // wait for the request to finish

    await Promise.all(createdAccResult);
    console.log('Done!');

    accId = createdAccResult.data.accountId;
    console.log(JSON.stringify("ACCOUNT CREATED:" + accId));
} catch(err) {
    console.log("ERROR Create acc:" + err );
  }

  try{
    var initUnAuthBody = JSON.stringify(
        {
            "accountId": accId
        });
    
    var initUnAuth = {
      method: 'post',
      url: url2,
      headers: awsHeaders,
      data : initUnAuthBody
    };
    
    const initUnAuthResult = await axios(initUnAuth); // wait for the request to finish
    console.log(JSON.stringify("Init unAuth for:" +accId+", with response:" + initUnAuthResult.status));

  }catch(err) {
    console.log("ERROR unautinit:" + err);
  }

  try{
    var provisionBody = JSON.stringify(
        {
            "name":  accId,
            "active": "1"

        });
    
    var provision = {
      method: 'post',
      url: url3,
      headers: awsHeaders,
      data : provisionBody
    };

    const provisionResult = await axios(provision); // wait for the request to finish
    console.log(JSON.stringify("Provision for:" + accId+", with response:" +  provisionResult.status));

}catch(err) {
    console.log("ERROR provision:" + err);
  }

  try{
    var salesForceRecordody = JSON.stringify(
        {
            "email": emails[item],
            "accountId":  accId,

        });
    
    var salesForceRecord = {
      method: 'post',
      url: url4,
      headers: awsHeaders,
      data : salesForceRecordody
    };

    const salesForceRecordResult = await axios(salesForceRecord); // wait for the request to finish

    console.log(JSON.stringify("SalesForce Record for:" +accId+", with response:" + salesForceRecordResult.status));

    accCreatedList.push(accId); // Push to created list only when all steps are done
}catch(err) {
    console.log("ERROR Salesforce:" + err);
  }

    }
 }

结果是,如您所见,返回 400 错误,但我不知道在 axios 中使用 async await 时如何从服务器获取完整响应,使用 then 和抓住,但我只能得到这个简单的回应。

在控制台中打印正文/标题时,一切似乎都很好,这与我之前所做的请求相同,但由于某种原因它在这里失败了......

Making :3 Accounts
ERROR Create acc:Error: Request failed with status code 400
ERROR unautinit:Error: Request failed with status code 400
ERROR provision:Error: Request failed with status code 400
ERROR Salesforce:Error: Request failed with status code 400
ERROR Create acc:Error: Request failed with status code 400
ERROR unautinit:Error: Request failed with status code 400
ERROR provision:Error: Request failed with status code 400
ERROR Salesforce:Error: Request failed with status code 400
ERROR Create acc:Error: Request failed with status code 400
ERROR unautinit:Error: Request failed with status code 400
ERROR provision:Error: Request failed with status code 400
ERROR Salesforce:Error: Request failed with status code 400

【问题讨论】:

    标签: javascript node.js asynchronous async-await axios


    【解决方案1】:

    使用 async/await 这相对简单:

    for(...) {
       const result = await axios(...); // wait for the request to finish
       // do something with your result
    }
    

    【讨论】:

    • 但是,如果我在循环中使用 await,它必须放在函数中,它说它必须在异步函数中 - 我该如何解决?
    • 是的,您需要将它放在异步函数中。如果你想在 JS 中编写异步代码,你真的应该阅读 async/await。在 StackOverflow 上,我们尝试解决其他人遇到的问题并教他们一点。但不要对已经有据可查的东西(如 async/await)提供广泛的课程。 @makat
    【解决方案2】:

    基本上,您需要让您的函数返回 axios 正在创建的 Promise。您的样本间距有点难以分辨,但看起来只需在此行中添加 return 即可:

    return axios(createAcc)
    

    然后,不是使用setTimeout 和循环,而是需要进行第一次调用,等待它完成,然后在then() 方法中,如果有的话,进行下一次调用:

    var merchantsToCreate = getFromSomewhere();
    var currentIndex = 0;
    
    function makeNextAccount() {
      if (currentIndex < merchantsToCreate.length - 1) {
        currentIndex++;
        accountCreationFlow(merchantsToCreate[i], emails[i])
          .then(makeNextAccount); // <- will make the next account
      }
    }
    
    makeNextAccount(); // kick off the "loop"
    

    【讨论】:

    • 我尝试用 await 来做,但似乎由于某种原因失败了
    • 如果您可以根据您的尝试更新您的答案,也许我们可以提供帮助。这是一种适当的技术,所以它可能只是一些错字或什么的。
    • OKAY - 全部修复 - 使用了 for..in 循环,它似乎工作,我不知道为什么它之前失败,我删除了一些日志记录,也许我打破了一些东西并没有通知
    【解决方案3】:

    我能够用来解决此问题的唯一解决方案是:

    1. 使用放置在异步函数中的 For..in 循环
    2. 使用这种请求方式:const provisionResult = await axios(provision)

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 2020-06-07
      • 2017-10-26
      • 1970-01-01
      • 2016-07-11
      • 2011-08-28
      • 2021-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多