javascript 在异步函数中使用setTimeout [重复]

sigwle7e  于 2023-03-16  发布在  Java
关注(0)|答案(6)|浏览(160)

此问题在此处已有答案

(17个答案)
8个月前关闭。
我有一个异步函数,它等待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)
}

有人帮忙吗?

bq9c1y66

bq9c1y661#

await只适用于承诺。您需要将setTimeout Package 在承诺中:

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

await waitFor(500);
lpwwtiir

lpwwtiir2#

setTimeout()不返回一个Promise,但是你可以像这样把它 Package 起来。我还稍微清理了一下你的代码的其余部分。

async function processMatchingSchools(customer_metafield_url) {
  for (const item of customer_metafield_url) {
    await new Promise(resolve => {
      setTimeout(resolve, 500)
    })

    const { data: { metafields } } = await axios.get(item)

    for ({ value, owner_id } of Object.values(metafields)) {
      if (value === schoolName) {
        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)
}
ecfsfe2w

ecfsfe2w3#

setTimeout不返回承诺,因此无法进行await编辑。
您可以创建自己的基于承诺的setTimeout并使用它。

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

await setTimeoutPromise(500);
qjp7pelc

qjp7pelc4#

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

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")
})()
oyjwcjzk

oyjwcjzk5#

你需要创造新的承诺比如说

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

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

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

juzqafwq6#

我创建了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)
}

相关问题