通过学习阮一峰的《ECMAScript 6 入门》,自己总结的一些关于 Promise
容易忘记的知识点
new Promise((resolve, reject) => {
reject()
resolve()
console.log('hello')
}).then(() => {
console.log('resolve');
}, () => {
console.log('reject');
})
for (let i = 0; i < 100; i++) {
console.log('hi');
}
/*输出
hello
hi
hi
...
hi
reject
Promise
新建后就会立即执行。回调函数resolve
和reject
将在当前脚本所有同步任务执行完才会执行,而且在Promise
中只能执行两者中的一个回调函数.调用resolve或reject并不会终结Promise
函数执行,后面的console.log(‘hello’)还是会执行,并且会首先打印出来,这是因为立即回调函数是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
let p1 = new Promise((resolve, reject) => {
reject()
resolve()
})
let p2 = new Promise((resolve, reject) => {
resolve(p1)
}).then(() => {
console.log('resolve');
}, () => {
console.log('reject');
})
/*输出
reject
p2的resolve
方法返回的是p1
。由于p2
返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。当resolve
或reject
函数的参数为Promise
对象,这时参数的状态会决定当前Promise
对象的状态
Promise
可以通过then()
方法进行链式编程,解决回调地狱的问题,并且结构更加清晰。
new Promise((resolve, reject) => {
resolve('hello')
}).then((str) => {
console.log('resolve', str);
return new Promise((resolve, reject) => {
resolve('world')
})
}).then((str) => {
console.log('resolve', str);
return new Promise((resolve, reject) => {
reject('nihao')
})
}).then((str) => {
console.log('resolve', str);
}, (str) => {
console.log('reject', str);
})
/*输出
resolve hello
resolve world
reject nihao
当回调函数返回值是Promise
对象,可以进行链式编程,而且很明显,Promise
对象的状态相互没有影响,也就是下一个回调函数的状态由新返回的Promise
对象决定
Promise
内部的错误不会影响到 Promise
外部的代码,也就是说Promise
内部的错误不会终止进程,会继续执行程序
new Promise((resolve, reject) => {
resolve(x + 2)
}).then(val => {
console.log('resolve', val);
}).catch(err => {
console.log('错误:' + err);
})
setTimeout(() => {
console.log('123');
}, 1000)
/*输出
错误:ReferenceError: x is not defined
123
注意:如果Promise
实例对象中的异步操作抛出错误,那么进程会终止,如下
new Promise((resolve, reject) => {
resolve(2)
setTimeout(() => {
throw new Error('err')
}, 1000)
}).then(val => {
console.log('resolve', val);
}).catch(err => {
console.log('错误:' + err);
})
setTimeout(() => {
console.log('1111111');
}, 2000)
/*输出
resolve 2
Error: err //进程终止
上面代码中,Promise
指定在下一轮“事件循环”再抛出错误。到了那个时候,Promise
的运行已经结束了,所以这个错误是在 Promise
函数体外抛出的,会冒泡到最外层,成了未捕获的错误。