Promise(一)
我的 promise 学习笔记,参考了 阮一峰的入门教程
1. 含义
Promise
的状态只能从 pending
到 fulfilled
和从 pending
到 rejected
,不会发生其他的变化,而且状态一旦改变就不会再次改变。
注意 Promise
也是有一些缺点的,并不完全适用所有的场景:无法取消,吃掉错误,无法得知处于哪个阶段。
2. 基本用法
Promise
构造函数有一个函数作为参数,这个函数有两个参数 ,resolve
和 reject
。(resolve
和 reject
并不是 Promise
构造函数的参数)
Promise 中的并发模型
then
方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行
调用
resolve
或reject
并不会终结Promise
的参数函数的执行
new Promise((resolve, reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
// 2
// 1
then
方法用于处理异步结果,所以在其他同步任务之后执行。关于 Javascript
的并发模型和事件循环,可以参考这个链接。
3. then() 方法
-
then
方法有两个参数,第二个参数是 rejected 状态的回调let foo = new Promise((resolve, reject) => { // reject('wrong'); resolve('ok'); }); foo .then( (res) => { console.log('then...'); console.log(res, x); }, (error) => { console.log('then--error...'); console.log(error); throw new Error(error + 'throw'); } ) .catch((error) => { console.log('catch...'); console.log(error.message); });
调用
resolve(ok)
返回then... catch... x is not defined
第一个参数中
x
未定义,这个错误会被外面的catch
,而不是then
的第二个参数。调用
reject('wrong')
返回then--error... wrong catch... wrong--throw
调用
reject
方法,如果then
方法第二个参数的回调存在,则被这个回调捕获,这个回调中发生的错误会被外面的catch
捕获。
4. catch() 方法
-
在上面
then
中解释过,catch
会捕获then
抛出的错误...返回一个 Promise 对象,如果该对象状态变为 resolved,则会调用 then()方法指定的回调函数;如果异步操作抛出错误,状态就会变为 rejected,就会调用 catch()方法指定的回调函数,处理这个错误。另外,then()方法指定的回调函数,如果运行中抛出错误,也会被 catch()方法捕获。
-
Promise
状态已经变成resolved
之后再抛出错误是无效的(同理,先抛错误再resolve
,resolve
也是不会执行的)。const promise = new Promise(function(resolve, reject) { resolve('ok'); throw new Error('test'); }); promise .then(function(value) { console.log(value) }) .catch(function(error) { console.log(error) }); // ok
-
吃掉错误:没有
catch
进行捕获的错误,不会传递到外层,同时不会退出进程,其他代码照样执行。new Promise(function (resolve, reject) { // 下面一行会报错,因为x没有声明 resolve(x + 2); }).then(function () { console.log('everything is great'); }); setTimeout(() => { console.log(123); }, 2000); // UnhandledPromiseRejectionWarning: ReferenceError: x is not defined // 123
5. finally() 方法
不管 promise 最后的状态,在执行完 then 或 catch 指定的回调函数以后,都会执行 finally 方法指定的回调函数。