【问题标题】:How to run a few API calls in a loop and then use callback function如何在循环中运行几个 API 调用然后使用回调函数
【发布时间】:2021-11-14 09:08:52
【问题描述】:

我正在尝试编写一个函数,但似乎无法弄清楚如何在字符串数组上运行 API 调用循环,并且只有在完成所有 API 调用后才能调用回调函数。无论我尝试什么,要么函数失败,要么回调函数被调用得太快。

这是我的代码:

exports.handler = function (context, event, callback) {
  const client = context.getTwilioClient();

  const sidArr = [];
  const cc = event.ccSid;
  const exp = event.expSid;
  const cvc = event.cvcSid;

  sidArr.push(cc, exp, cvc);

  const resArr = [];

  for (var i = 0; i < sidArr.length; i++) {
    client
      .messages(sidArr[i])
      .update({ body: '' })
      .then((message) => {
        if (resArray.length == sidArr.length) {
          callback(null, resArray);
        } else {
          resArray.push(message.sid);
        }
      });
  }
};

【问题讨论】:

    标签: javascript loops promise callback twilio-functions


    【解决方案1】:

    update 方法返回一个Promise。循环sidArr 数组并为数组中的每个项目调用messagesupdate 方法。将返回的Promise 存储在一个新数组中。

    您可以使用静态Promise.all 函数等待数组中的所有承诺完成。结果将是所有已解决的承诺的数组。

    然后再次循环每个结果以提取sid 属性。

    exports.handler = function (context, event, callback) {
      const client = context.getTwilioClient();
    
      const sidArr = [];
      const cc = event.ccSid;
      const exp = event.expSid;
      const cvc = event.cvcSid;
    
      sidArr.push(cc, exp, cvc);
    
      const requests = sidArr.map(message =>
        client
          .messages(message)
          .update({ body: "" })
          .catch(error => console.log(error))
      );
    
      Promise.all(requests)
        .then(messages => messages.map(({ sid }) => sid))
        .then(sids => callback(sids))
    };
    

    【讨论】:

    • 我运行了您的代码并收到以下语法错误 "message": "Unexpected token '}'" 我想我不能在 Twilio 运行时函数中使用 asyncawait,因为它在代码编辑器中显示警告。也许这就是我收到错误的原因。你能把它改成没有它吗?
    • 我已经更新了没有异步/等待的答案。另外我忘了调用callback 函数。
    • 我尝试了你更新的答案并得到了这个错误UnhandledPromiseRejectionWarning: Unhandled promise rejection: undefined(我修复了语法错误)
    • 这可能意味着client.messages(message).update({ body: "" }) 请求之一没有成功更新。该错误表明update 方法返回的promise 未处理。我们可以通过在update 方法之后添加catch() 方法来处理它。只要update 方法中发生错误,就会运行此catch 方法。否则会被跳过。添加 catch 块可能会让您更深入地了解错误的性质。
    【解决方案2】:

    如果您不能使用asyncawait,那么您可以使用Promise.all() 并像这样并行运行它们:

    并行运行:

    let promises = [];
    for (var i = 0; i < sidArr.length; i++) {
      promises.push(
        client
          .messages(sidArr[i])
          .update({ body: '' })
          .then((message) => message.sid)
      );
    }
    Promise.all(promises)
      .then((results) => callback(null, results))
      .catch((err) => callback(err));
    

    当然,像这样将 Promise 变成普通的回调有点反模式。您真的应该只更改接口并将承诺返回给调用者,以便调用者可以直接在承诺上使用.then().catch()

    在没有asyncawait 的情况下按顺序运行它们:

    或者,如果您想在不使用asyncawait 的情况下按顺序(而不是并行)运行它们,那么您可以使用老式的异步迭代方式(我们在async/await 之前所做的) :

    function run(sidArr, callback) {
      let index = 0;
      let results = [];
    
      function next() {
        // check if we're done and call callback
        if (index >= sidArr.length) {
          // ensure callback is always called asynchronously
          //   even if sidArr is empty
          setImmediate(() => callback(null, results));
          return;
        }
        // still more to process
        client
          .messages(sidArr[index++])
          .update({ body: '' })
          .then((message) => {
            // save result and do next iteration of loop
            results.push(message.sid);
            next();
          })
          .catch(callback);
      }
    
      next();
    }
    
    run(sidArr, putYourCompletionCallbackHere);
    

    使用asyncawait 依次运行它们:

    为了完整起见,当您可以使用 asyncawait 时,以下是按顺序运行它们的方法:

    async function run(sidArr, callback) {
      try {
        let results = [];
        for (var i = 0; i < sidArr.length; i++) {
          let data = await client.messages(sidArr[i]).update({ body: '' });
          results.push(data.sid);
        }
        callback(null, results);
      } catch (e) {
        callback(e);
      }
    }
    
    run(sidArr, putYourCompletionCallbackHere);
    

    【讨论】:

      猜你喜欢
      • 2013-11-14
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 2015-12-26
      • 1970-01-01
      • 2020-02-13
      相关资源
      最近更新 更多