1.正常JS事件循环
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
Promise.resolve().then(() => setTimeout(() => console.log(4)));
Promise.resolve().then(() => console.log(5));
setTimeout(() => console.log(6));
console.log(7);
1735264
2.promise.then需要promise状态变成resolve才会执行
const promise = new Promise((resolve, reject) => {
console.log(1);
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);
124
3.需要注意的是,直接打印promise1,会打印出它的状态值和参数
const promise1 = new Promise((resolve, reject) => {
console.log('promise1')
resolve('resolve1')
})
const promise2 = promise1.then(res => {
console.log(res)
})
console.log('1', promise1);
console.log('2', promise2);
promise1
1 Promise{<resolved>: resolve1}
2 Promise{<pending>}
resolve1
代码执行过程如下:
- script是一个宏任务,按照顺序执行这些代码;
- 首先进入Promise,执行该构造函数中的代码,打印
promise1
; - 碰到
resolve
函数, 将promise1
的状态改变为resolved
, 并将结果保存下来; - 碰到
promise1.then
这个微任务,将它放入微任务队列; promise2
是一个新的状态为pending
的Promise
;- 执行同步代码1, 同时打印出
promise1
的状态是resolved
; - 执行同步代码2,同时打印出
promise2
的状态是pending
; - 宏任务执行完毕,查找微任务队列,发现
promise1.then
这个微任务且状态为resolved
,执行它。
4.由于Promise
的状态是pending
的时候,所以promise.then
先不执行;
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => {
console.log("timerStart");
resolve("success");
console.log("timerEnd");
}, 0);
console.log(2);
});
promise.then((res) => {
console.log(res);
});
console.log(4);
1
2
4
timerStart
timerEnd
success
代码执行过程如下:
- 首先遇到Promise构造函数,会先执行里面的内容,打印
1
; - 遇到定时器
steTimeout
,它是一个宏任务,放入宏任务队列; - 继续向下执行,打印出2;
- 由于
Promise
的状态此时还是pending
,所以promise.then
先不执行; - 继续执行下面的同步任务,打印出4;
- 此时微任务队列没有任务,继续执行下一轮宏任务,执行
steTimeout
; - 首先执行
timerStart
,然后遇到了resolve
,将promise
的状态改为resolved
且保存结果并将之前的promise.then
推入微任务队列,再执行timerEnd
; - 执行完这个宏任务,就去执行微任务
promise.then
,打印出resolve
的结果。
5.宏任务队列有两个任务,第一个任务产生微任务,那么会在宏任务1执行完去执行微任务,最后执行微任务
Promise.resolve().then(() => {
console.log('promise1');
const timer2 = setTimeout(() => {
console.log('timer2')
}, 0)
});
const timer1 = setTimeout(() => {
console.log('timer1')
Promise.resolve().then(() => {
console.log('promise2')
})
}, 0)
console.log('start');
start
promise1
timer1
promise2
timer2
6.then(2)等于没有;Promise.resolve方法的参数如果是一个原始值,会传给回调函数。
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3)) //不清楚
.then(console.log)
1
Promise {<fulfilled>: undefined}
then方法接受的参数是函数,而如果传递的并非是一个函数,它实际上会将其解释为then(null),这就会导致前一个Promise的结果会传递下面。then(2)等于没有
Promise.resolve方法的参数如果是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为resolved,Promise.resolve方法的参数,会同时传给回调函数。
7.throw是抛出错误,遇到执行一次,然后=rejected
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
})
const promise2 = promise1.then(() => {
throw new Error('error!!!')
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
console.log('promise1', promise1)
console.log('promise2', promise2)
}, 2000)
promise1 Promise {<pending>}
promise2 Promise {<pending>}
Uncaught (in promise) Error: error!!!
promise1 Promise {<fulfilled>: "success"}
promise2 Promise {<rejected>: Error: error!!}
8.return 2会被包装成resolve(2)
Promise.resolve(1)
.then(res => {
console.log(res);
return 2;
})
.catch(err => {
return 3;
})
.then(res => {
console.log(res);
});
1
2
9.return会被当做resolve()
Promise.resolve().then(() => {
return new Error('error!!!')
}).then(res => {
console.log("then: ", res)
}).catch(err => {
console.log("catch: ", err)
})
"then: " "Error: error!!!"
返回任意一个非 promise 的值都会被包裹成 promise 对象,因此这里的return new Error('error!!!')
也被包裹成了return Promise.resolve(new Error('error!!!'))
,因此它会被then捕获而不是catch。