有这么一道问题:
let p1 = new Promise(resolve => {
setTimeout(resolve('p1'), 1000)
})
let p2 = new Promise(resolve => {
setTimeout(resolve('p2'), 500);
});
Promise.race([p1, p2])
.then(value => {
console.log(value)
});
猜猜输出的会是什么?
大家可以试试看后面就明白,题目的本意是比较两个promise哪个更快,那么500毫秒的肯定更快,然而结果确是输出p1。为什么呢?
问题出在setTimeout上。
setTimeout的第一个参数,在执行到setTimeout语句的时候,就会执行。而resolve本身就是一个函数,当你带上了括号,它就立即执行了。而p1在p2之前,那么自然永远是p1先resolve了。所以,不管时间怎么改变,输出的永远是p1。
那么,正确的写法应该是什么呢?有两种解决方案:
一、setTimeout的第一个参数不要写成函数调用,而是写成函数的引用。
也就是:
setTimeout(resolve, 1000);
有朋友可能会问,那这样怎么传参呢?实际上,setTimeout支持第三个参数,我们可以这样传参。这也是Promise里经常能看到的调用方法:
setTimeout(resolve, 1000, "p1");
这样就只会在1秒后,才真正把参数传递到函数中并执行。
二、用一个匿名函数:
setTimeout(() => {
resolve("p1");
}, 1000);
这样也能避免函数立即调用,而是在1秒后再调用。
感觉setTimeout是一个很神奇的函数,在学习js原理的时候,经常能看到它的身影。认真学习这个函数,有助于对js原理的理解。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。