【问题标题】:Using a setTimeout in a async function在异步函数中使用 setTimeout
【发布时间】:2018-07-05 22:21:28
【问题描述】:

我有一个异步函数,它在继续之前等待 axios 调用完成。问题是我需要将 axios 调用的超时设置为半秒,这样我就不会达到 shopify API 调用限制。

async function processMatchingSchools(customer_metafield_url) {
  for (const item of customer_metafield_url) {
    await axios.get(item).then((res) => {
      for (key in res.data.metafields) {
        if (res.data.metafields[key].value === schoolName) {
          id_for_each_student.push(shopifyAdmin + "/customers/" + res.data.metafields[key].owner_id + "/metafields.json")
        }
      }
    })
  }
  console.log("Customer metafields to search", id_for_each_student)
  processOwnerIds(id_for_each_student)
}

当我尝试设置 setTimeout 时,它会调用 setTimeout 并在完成 axios 调用之前继续前进。

async function processMatchingSchools(customer_metafield_url) {
  for (const item of customer_metafield_url) {
    await setTimeout(function(item) {
      axios.get(item).then((res) => {
        for (key in res.data.metafields) {
          if (res.data.metafields[key].value === schoolName) {
            id_for_each_student.push(shopifyAdmin + "/customers/" + res.data.metafields[key].owner_id + "/metafields.json")
          }
        }
      })
    }, 500)
  }
  console.log("Customer metafields to search", id_for_each_student)
  processOwnerIds(id_for_each_student)
}

有什么帮助吗?

【问题讨论】:

  • 好吧,setTimeout 不是基于承诺的,所以尝试等待它有点奇怪。

标签: javascript asynchronous async-await settimeout axios


【解决方案1】:

await 仅适用于承诺。 您需要将setTimeout 包装在一个承诺中:

const waitFor = delay => new Promise(resolve => setTimeout(resolve, delay));

await waitFor(500);

【讨论】:

    【解决方案2】:

    setTimeout() 不会返回 Promise,但您可以将其包装成这样。我还稍微清理了您的其余代码。

    async function processMatchingSchools(customer_metafield_url) {
      for (const item of customer_metafield_url) {
        await new Promise(resolve => {
          setTimeout(resolve, 500)
        })
    
        await axios.get(item).then((res) => {
          Object.values(res.data.metafields).filter(
            ({ value }) => value === schoolName
          ).forEach(({ owner_id }) => {
            id_for_each_student.push(`${shopifyAdmin}/customers/${owner_id}/metafields.json`)
          })
        })
      }
    
      console.log("Customer metafields to search", id_for_each_student)
    
      processOwnerIds(id_for_each_student)
    }
    

    【讨论】:

    • 感谢大家帮助我:P 也感谢 Patrick 帮助我清理我的新手代码。
    【解决方案3】:

    setTimeout 不返回承诺,因此不能是awaited。

    您可以创建自己的基于 Promise 的 setTimeout 并使用它。

    const setTimeoutPromise = timeout => new Promise(resolve => {        
      setTimeout(resolve, timeout);
    });
    
    await setTimeoutPromise(500);
    

    【讨论】:

      【解决方案4】:

      创建一个sleep 函数,该函数返回一个您可以使用的承诺,如下所示:

      const sleep = (milliseconds=500) => new Promise(resolve => setTimeout(resolve, milliseconds))
      

      并在异步函数中使用它:

      (async () => {
        console.log("function invoked...")
        await sleep(500)
        console.log("I got here about 500 milliseconds later")
      })()
      

      【讨论】:

      • 应该是const sleep = ms => {return new Promise(resolve => setTimeout(resolve, ms));}
      【解决方案5】:

      你需要像这样创建新的承诺

      function delay(ms){
       return new Promise(resolve => setTimeout(resolve, ms))
      }
      

      然后在调用 API 之前在你的代码中使用它

      ...
      await delay(500)
      await axios.get(item).then((res) => {
      ...
      

      【讨论】:

        【解决方案6】:

        我创建了 setTimeout2 函数,它的工作原理与 promise 相同:

        const setTimeout2 = (callback, ms) => {
          return new Promise(resolve => setTimeout(() => {
            callback();
            resolve();
          }, ms));
        } 
        

        所以,一共(注意到 setTimeout2 变化):

        async function processMatchingSchools(customer_metafield_url) {
          for (const item of customer_metafield_url) {
            await setTimeout2(function(item) {
              axios.get(item).then((res) => {
                for (key in res.data.metafields) {
                  if (res.data.metafields[key].value === schoolName) {
                    id_for_each_student.push(shopifyAdmin + "/customers/" + res.data.metafields[key].owner_id + "/metafields.json")
                  }
                }
              })
            }, 500)
          }
          console.log("Customer metafields to search", id_for_each_student)
          processOwnerIds(id_for_each_student)
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-09-25
          • 1970-01-01
          • 2020-06-29
          • 2022-10-14
          • 1970-01-01
          • 1970-01-01
          • 2022-01-21
          • 1970-01-01
          相关资源
          最近更新 更多