【问题标题】:how setTimeout works in promise in javascript?setTimeout 如何在 JavaScript 中实现 promise?
【发布时间】:2018-11-16 11:14:32
【问题描述】:
我有一个问题,我不知道 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。
【问题讨论】:
标签:
javascript
promise
settimeout
【解决方案1】:
在 t = 0
- 创建了一个以
timeout1 开头的承诺 p13,等待时间为 3 秒
- 会创建一个以
timeout2 开头的承诺 p14,等待时间为 1 秒
在 t = 1000
-
timeout2 触发回调函数,将p14 与promise p13 链接起来
-
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);
如您在上面的示例中所见,承诺p13 的超时甚至在延迟5000 毫秒的setTimeout 的回调执行之前就被触发了。
结论 - 当您创建一个promise 对象时,promise 对象的状态处于挂起状态,但是,实际功能会被触发。
【解决方案2】:
你的超时承诺是异步的。
当你创建 p13 时,它直接开始了它的超时时间,也就是 3000。
它不是在等待 p14 的 1000。 (这是你的想法)
详细了解您的代码预期结果:
- 如果您在 p14 中输入任何小于 3000 的数字,它将以 300x 解析。如果你投入超过4000,那么它将被拒绝。 (虽然超时不是那么准确,所以它更像是 3000 / 4000 左右)
【解决方案3】:
当你创建一个新的 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 毫秒后有效。
【解决方案4】:
这就是你如何使它达到 4000
使 p13 成为一个函数
解决(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);
});