setTimeout 如何在 javascript 中发挥作用?

how setTimeout works in promise in javascript?

我有一个问题,我不知道 setTimeout 是如何工作的,我必须计时:

const start = new Date().getTime();
function a() {
  setTimeout(() => {
    console.log('output', new Date().getTime() - start);
  }, 3000);
}

setTimeout(a, 1000);

输出:4000

然后我把代码改成这样:

const start = new Date().getTime();
const p13 = new Promise((resolve,reject) => {
  setTimeout(() => {
    reject(new Error('error'));
  },3000);
});

const p14 = new Promise((resolve,reject) => {
  const s = new Date().getTime();
  setTimeout(() => {
    resolve(p13);
  },1000);
});

p14.then((value) => {
  console.log(value, 'value');
}).catch((error) => {
  const end = new Date().getTime();
  console.log('output:', end - start);
});

输出:3000,我不知道为什么?它应该输出 4000。为什么是 3000。

您的超时承诺是异步的。

当你创建p13时,它直接启动了它的超时时间,即3000。 它不是在等待 p14 的 1000。 (这就是你的想法)

有关代码预期结果的更多详细信息:

  • 如果你在 p14 中输入任何小于 3000 的数字,它将以 300x 解析。如果你放超过4000,那么它就会被拒绝。 (虽然超时不是那么准确所以它更像是大约 3000 / 4000)

这是你如何让它达到 4000

使 p13 成为函数

解决(p13());

现在你要等到 p14 才能开始 p13 "completes"

const start = new Date().getTime();
const p13 = () => new Promise((resolve,reject) => {
  setTimeout(() => {
    reject(new Error('error'));
  },3000);
});

const p14 = new Promise((resolve,reject) => {
  const s = new Date().getTime();
  setTimeout(() => {
    resolve(p13());
  },1000);
});

p14.then((value) => {
  console.log(value, 'value');
}).catch((error) => {
  const end = new Date().getTime();
  console.log('output:', end - start);
});

当您创建一个新的 Promise 时,您作为构造函数参数传递的函数会立即执行。因此 p13 超时将在 Promise 创建后 3000 毫秒后调用拒绝 - 而不是在它传递给 resolve 函数后 3000 毫秒。如果你想让你的 Promises 一个接一个地 运行 ,你可以将你的代码重构为这样的东西:

const start = new Date().getTime();
const p13 = () => {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            reject(new Error('error'));
        },3000);
    });
}

const p14 = new Promise((resolve,reject) => {
    const s = new Date().getTime();
    setTimeout(() => {
        resolve(p13());
    },1000);
});

p14.then((value) => {
    console.log(value, 'value');
}).catch((error) => {
    const end = new Date().getTime();
    console.log('output:', end - start);
});

p13 现在是一个创建 Promise 的函数。该函数在 1000 毫秒后执行,创建并返回新的 Promise,并安排另一个超时。第二次超时在另一个 3000 毫秒后拒绝 Promise,因此在程序启动后 4000 毫秒后有效。

在 t = 0

  • 创建了一个 promise p13 开始 timeout1 等待时间为 3 秒
  • 创建了一个 promise p14,它以 1 秒的等待时间
  • 开始 timeout2

在 t = 1000

  • timeout2 触发回调函数,用 promise p13
  • 链接 p14
  • timeout1已穿越1000ms

在 t = 3000

  • timeout1触发回调函数,拒绝promise并输出计算

再举个例子

const start = new Date().getTime();
const p13 = new Promise((resolve,reject) => {
  setTimeout(() => {
    const end = new Date().getTime();
    console.log('output:', end - start);
    reject(new Error('error'));
  },3000);
});

const p14 = new Promise((resolve,reject) => {
  const s = new Date().getTime();
  setTimeout(() => {
    resolve(p13);
  },1000);
});

setTimeout(function(){
  p14.then((value) => {
    console.log(value, 'value');
  }).catch((error) => {
    console.log('error');
  });
}, 5000);

正如您在上面的示例中看到的,甚至在延迟 5000 毫秒执行 setTimeout 的回调之前,承诺 p13 的超时就已被触发。

结论 - 当您创建一个 promise 对象时,promise 对象的状态处于挂起状态,但是,实际功能会被触发。