Javascript 为什么我的do..while循环不能在异步等待代码中正确执行setTimeout?

Javascript 为什么我的do..while循环不能在异步等待代码中正确执行setTimeout?,javascript,promise,async-await,do-while,Javascript,Promise,Async Await,Do While,我有一个do..while循环,它执行承诺并等待响应。在处理或接收响应时,循环需要继续。但是,在Promise中有一个setTimeout函数 这里的目标是使do..while循环的do语句中的函数respo=await promise1.thenresp=>resp仅在2秒后被调用。这仅仅是为了让我正在使用的API完成它的工作 当前发生的情况是,setTimeout被调用一次,循环几乎立即重复相同的响应,这表明2秒钟的中断不起作用 我做错了什么 const promise1 = new Pro

我有一个do..while循环,它执行承诺并等待响应。在处理或接收响应时,循环需要继续。但是,在Promise中有一个setTimeout函数

这里的目标是使do..while循环的do语句中的函数respo=await promise1.thenresp=>resp仅在2秒后被调用。这仅仅是为了让我正在使用的API完成它的工作

当前发生的情况是,setTimeout被调用一次,循环几乎立即重复相同的响应,这表明2秒钟的中断不起作用

我做错了什么

const promise1 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(tasks(resStatus.data.task.id, tokenTenant))
  }, 2000);
})

do {
  respo = await promise1
  console.log(respo.data)
} while (respo.data.status === "Processing" || respo.data.status === "Received");
。 .

对于那些古玩爱好者,一些样本回答问题得到了解决:

有几点需要说明:

承诺只能解决一次。 传递给承诺构造函数的回调将立即执行,以后不再执行 解决方案:移动常量promise1=。。。循环内的定义。这样,您就可以在每次迭代中创建一个新的承诺。

需要指出的几点:

承诺只能解决一次。 传递给承诺构造函数的回调将立即执行,以后不再执行
解决方案:移动常量promise1=。。。循环内的定义。这样,每次迭代都会创建一个新的承诺。

这是关于承诺的一个更常见的误解。它不是使用调用传递到新promise中的函数的promise,而是创建一个promise。executor中的代码也被同步调用:在promise1收到承诺之前调用setTimeout,然后在大约两秒钟后调用它

在代码中,您正在设置一个setTimeout调用,然后等待它完成,如果循环重复,您将再次等待相同的结果。当然,由于超时已经完成,所以您可以更快地完成

要重试操作,您需要在循环中创建承诺,以便在executor函数中重新运行代码:

function getTask() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(tasks(resStatus.data.task.id, tokenTenant))
    }, 2000);
  });
}

do {
  respo = await getTask();
  console.log(respo.data)
} while (respo.data.status === "Processing" || respo.data.status === "Received");
为了清晰起见,我使用了一个传统的getTask函数。如果愿意,您可以将其与其他功能一起设置为箭头功能:

const getTask = () => new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(tasks(resStatus.data.task.id, tokenTenant))
  }, 2000);
});

这是对承诺更常见的误解之一。它不是使用调用传递到新promise中的函数的promise,而是创建一个promise。executor中的代码也被同步调用:在promise1收到承诺之前调用setTimeout,然后在大约两秒钟后调用它

在代码中,您正在设置一个setTimeout调用,然后等待它完成,如果循环重复,您将再次等待相同的结果。当然,由于超时已经完成,所以您可以更快地完成

要重试操作,您需要在循环中创建承诺,以便在executor函数中重新运行代码:

function getTask() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(tasks(resStatus.data.task.id, tokenTenant))
    }, 2000);
  });
}

do {
  respo = await getTask();
  console.log(respo.data)
} while (respo.data.status === "Processing" || respo.data.status === "Received");
为了清晰起见,我使用了一个传统的getTask函数。如果愿意,您可以将其与其他功能一起设置为箭头功能:

const getTask = () => new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(tasks(resStatus.data.task.id, tokenTenant))
  }, 2000);
});

承诺只能解决一次,然后才能继续解决。promise构造函数回调总是执行一次,而且只执行一次..thenresp=>resp就像在同步代码中执行resp=resp一样,它本质上是一个no-op.Ah,谢谢@trincot。您建议的最佳和最干净的替代方案是什么?将const promise1=移动到循环中。这样,每次迭代都会创建一个新的承诺。就在你发布回复之前,我已经把它修好了承诺只能解决一次,然后才能继续解决。promise构造函数回调总是执行一次,而且只执行一次..thenresp=>resp就像在同步代码中执行resp=resp一样,它本质上是一个no-op.Ah,谢谢@trincot。您建议的最佳和最干净的替代方案是什么?将const promise1=移动到循环中。这样,每次迭代都会创建一个新的承诺。就在你发布回复之前,我已经把它修好了呜呜呜!先生,你是一台机器!非常感谢。它就像一个符咒,呜呜呜!先生,你是一台机器!非常感谢。这种方法的另一个好处是它将getTask函数从主块中分离出来,这样它就可以存在于库中并在其他代码中重用。感谢您提供的信息!谢谢你的建议。我已经按照@trincot的建议更新了我的代码。我也会试试你的。@RichS,我听到了。这是非常有意义的,这种方法的另一个好处是它将getTask函数从主块中分离出来,这样它就可以存在于库中并在其他代码中重用。感谢您提供的信息!谢谢你的建议。我已按照@trinco更新了我的代码
t的建议。我也会试试你的。@RichS,我听到了。这绝对有道理