setTimeout如何在JavaScript中的Promise中工作?

时间:2018-11-16 11:14:33

标签: javascript promise settimeout

我有一个问题,我不知道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。

4 个答案:

答案 0 :(得分:1)

超时承诺是异步的。

创建p13时,它将直接开始其超时,即3000。 它不是在等待p14中的1000。 (您的想法)

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

  • 如果在p14中输入小于3000的数字,则解析度为300x。如果您放置超过4000,则将被拒绝。 (尽管超时不是很准确,所以更像是3000/4000左右)

答案 1 :(得分:1)

在t = 0时

  • 创建了一个承诺p13,该承诺以3秒的等待时间开始timeout1
  • 创建了一个承诺p14,该承诺以1秒的等待时间开始timeout2

在t = 1000时

  • timeout2触发回调函数,将p14与承诺p13链接起来
  • timeout1穿越了1000毫秒

在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毫秒的p13回调之前,也会触发承诺setTimeout的超时。

结论-创建promise对象时,promise对象的状态为暂挂状态,但是实际功能会被触发。

答案 2 :(得分:0)

这是您将其变成4000的方式

使p13成为功能

resolve(p13());

现在直到p14“完成”您才开始p13

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);
});

答案 3 :(得分:0)

创建新的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毫秒后有效。