Open hzzzzzzzq opened 2 years ago
Promise 是异步编程的一种解决方案,在 Promise 之前,采用的是回调函数和事件,但是会存在一些问题,像回调地狱。而在 ES6 中,提供了 Promise 对象。
Promise
Promise 简单来讲,其实就是一个容器,用来存储异步事件(例如网络请求等)。
语法上来说,Promise 是一个对象,可以获取异步操作的消息。
pending
fulfilled
rejected
这里一般需要进行异步操作,但是为了学习方便,我们直接同步进行了。 Promise 构造函数接受一个函数作为参数,该函数的参数为 resolve 和 reject。 resolve 和 reject 是两个函数,有 JS 引擎提供,不需要自己部署。 resolve 函数作用是将 Promise 的状态从 pending 变为 resolved,并且将操作结果作为参数传递出去。 reject 函数作用是将 Promise 的状态从 pending 变为 rejected,并且将错误信息传递出去。 Promise 生成实例之后,可以调用 then 方法,其中包含两个函数参数。第一个函数包含 resolved 状态的结果,第二个包含 rejected 状态结果。两个函数都是可选参数。
resolve
reject
resolved
then
我们将 flag 比做异步操作,true 表示异步成功,false 表示异步失败。
flag
true
false
const promise = new Promise((resolve, reject) => { let flag = true; if (flag) { resolve('操作成功'); } else { reject('操作失败'); } }); promise.then( (value) => { console.log('value = ', value); }, (error) => { console.log('error = ', error); } );
从上面的代码来看,flag 为 true 时,会打印 value = 操作成功,为 false 时,打印 error = 操作失败。
value = 操作成功
error = 操作失败
我们来看看 then 的异步。 在 Promise 创建时,就会立即执行,而 then 会在当前脚本所有同步任务执行完才会执行。
const promise = new Promise((resolve, reject) => { console.log('1'); resolve('2'); }); promise.then((val) => { console.log(val); }); console.log('3'); // '1' // '3' // '2'
Promise.prototype.then() 方法作用是为 Promise 实例添加状态改变时的回调函数。 then 方法的第一个参数是 resolved 状态的回调函数,第二个参数是 rejected 状态的回调函数,它们都是可选的值,不一定必须传入。
Promise.prototype.then()
then 方法返回的是一个新的 Promise 实例,所以可以采用链式写法。
const promise = new Promise((resolve, reject) => { resolve('1'); }); promise .then((val) => { return val; }) .then((val) => { console.log(val); }); // '1'
Promise.prototype.catch() 方法就是在 then 方法时 reject 的情况,用于发生错误时的回调函数。
Promise.prototype.catch()
const promise = new Promise((resolve, reject) => { reject('1'); }); promise.catch((error) => { console.log(error); }); // '1'
如果在 Promise 中报错,进行错误抛出,状态会变为 rejected,就会调用 catch() 方法指定的回调函数,然后在其中处理错误。
catch()
当然,如果在运行过程中,抛出错误,也会被 catch 捕获。
catch
const promise = new Promise((resolve, reject) => { throw new Error('Error'); }); promise.catch((error) => { console.log(error); }); // 'Error'
Promise.prototype.finally() 方法不管 Promise 对象最后状态如何,都会进行执行。
Promise.prototype.finally()
const promise1 = new Promise((resolve, reject) => { resolve('成功'); }); promise1.finally(() => { console.log('执行finally'); }); // 执行finally const promise2 = new Promise((resolve, reject) => { reject('失败'); }); promise2.finally(() => { console.log('执行finally'); }); // 执行finally
Promise.all() 方法可以将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all()
const promise1 = new Promise((resolve, reject) => { resolve('1'); }); const promise2 = new Promise((resolve, reject) => { resolve('2'); }); const promise3 = new Promise((resolve, reject) => { resolve('3'); }); const promise = Promise.all([promise1, promise2, promise3]); promise.then((val) => { console.log(val); }); // ['1', '2', '3']
promise
// 我们将上面的代码其中一个 resolve 修改为 reject('1') const promise3 = new Promise((resolve, reject) => { reject('3'); }); const promise = Promise.all([promise1, promise2, promise3]); promise.then( (val) => { console.log(val); }, (error) => { console.log(error); // 3 } );
Promise.race() 方法同样是将多个实例包装为一个新的 Promise 实例。
Promise.race()
const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('1'); }, 1000); }); const promise2 = new Promise((resolve, reject) => { resolve('2'); }); const promise3 = new Promise((resolve, reject) => { resolve('3'); }); const promise = Promise.race([promise1, promise2, promise3]); promise.then((val) => { console.log(val); }); // 2
我们在第一个使用了 setTimeout,进行延迟,所以会是第二个的状态先改变,输出第二个的值。
setTimeout
Promise.allSettled() 方法,用来确定一组异步操作是否都结束了。 数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象,只有数组中的 Promsie 对象状态都发生改变时,返回的 Promise 对象才发生改变。 返回的值会接收到一个数组作为参数,该数组的每一个成员对应前面数组的每个 Promise 对象。
Promise.allSettled()
Promsie
const promise1 = new Promise((resolve, reject) => { reject('1'); }); const promise2 = new Promise((resolve, reject) => { resolve('2'); }); const promise3 = new Promise((resolve, reject) => { reject('3'); }); const promise = Promise.allSettled([promise1, promise2, promise3]); promise.then( (val) => { console.log(val); }, (error) => { console.log(error); } ); // [ // { // status: 'rejected', // reason: '1', // }, // { // status: 'fulfilled', // value: '2', // }, // { // status: 'rejected', // reason: '3', // }, // ];
数组成员对象的 status 属性的值只可能是 fulfilled 或 rejected,用来区别异步操作结果是成功(fulfilled)还是失败(rejected)。 如果是成功是会有 value 属性,记录成功值,如果失败,会有 reason 属性,记录失败原因。
status
value
reason
Promise.any() 方法,将一组 Promise 实例作为参数,包装成一个新的 Promise 实例并返回。
Promise.any()
const promise1 = new Promise((resolve, reject) => { reject('1'); }); const promise2 = new Promise((resolve, reject) => { resolve('2'); }); const promise3 = new Promise((resolve, reject) => { reject('error'); }); Promise.any([promise1, promise2, promise3]) .then((val) => { // 只要有一个成功 console.log(val); }) .catch((error) => { console.log(error); }); // 2
Promise.resolve() 方法有四种情况。
Promise.resolve()
const promise = Promise.resolve('请求成功'); // 等价于 const promise = new Promise((resolve) => resolve('请求成功'));
const promise = new Promise((resolve) => resolve('请求成功')); const promise1 = Promise.resolve(promise); promise1.then((val) => { console.log(val); });
thenable
const thenable = { then: function (resolve, reject) { resolve('成功'); }, }; const promise = Promise.resolve(thenable); promise.then((val) => { console.log(val); }); // 成功
const promise = Promise.resolve('成功'); promise.then((val) => { console.log(val); }); // 成功
注意,立即 resolve() 的 Promise 对象,是在本轮[事件循环(event loop)]()的结束时执行。
resolve()
const promise = Promise.resolve(); promise.then(() => { console.log('不带参数'); }); // 事件循环 // 不带参数 console.log('事件循环');
Promise.reject() 方法返回一个新 Promise 实例,该实例状态为 rejected。
Promise.reject()
const promise = Promise.reject('出错了的Promise'); // 同价 const promise = new Promise((resolve, reject) => { reject('出错了的Promise'); }); promise.then(null, (error) => { console.log(error); }); // 出错了的Promise
Promise 对象
含义
Promise 是异步编程的一种解决方案,在
Promise
之前,采用的是回调函数和事件,但是会存在一些问题,像回调地狱。而在 ES6 中,提供了Promise
对象。Promise
简单来讲,其实就是一个容器,用来存储异步事件(例如网络请求等)。语法上来说,
Promise
是一个对象,可以获取异步操作的消息。主要特点
pending
(进行中)、fulfilled
(完成)和rejected
(失败)。只受异步操作的结果,可以决定当前是哪种状态,其他任何操作都无法改变这个状态。pending
到fulfilled
和从pending
到rejected
。主要缺陷
pending
时,无法得知目前进展到哪个阶段。基本用法
这里一般需要进行异步操作,但是为了学习方便,我们直接同步进行了。
Promise
构造函数接受一个函数作为参数,该函数的参数为resolve
和reject
。resolve
和reject
是两个函数,有 JS 引擎提供,不需要自己部署。resolve
函数作用是将Promise
的状态从pending
变为resolved
,并且将操作结果作为参数传递出去。reject
函数作用是将Promise
的状态从pending
变为rejected
,并且将错误信息传递出去。Promise
生成实例之后,可以调用then
方法,其中包含两个函数参数。第一个函数包含resolved
状态的结果,第二个包含rejected
状态结果。两个函数都是可选参数。我们将
flag
比做异步操作,true
表示异步成功,false
表示异步失败。从上面的代码来看,
flag
为true
时,会打印value = 操作成功
,为 false 时,打印error = 操作失败
。我们来看看
then
的异步。 在Promise
创建时,就会立即执行,而then
会在当前脚本所有同步任务执行完才会执行。实例方法
Promise.prototype.then()
Promise.prototype.then()
方法作用是为Promise
实例添加状态改变时的回调函数。then
方法的第一个参数是resolved
状态的回调函数,第二个参数是rejected
状态的回调函数,它们都是可选的值,不一定必须传入。then
方法返回的是一个新的Promise
实例,所以可以采用链式写法。Promise.prototype.catch()
Promise.prototype.catch()
方法就是在then
方法时reject
的情况,用于发生错误时的回调函数。如果在
Promise
中报错,进行错误抛出,状态会变为rejected
,就会调用catch()
方法指定的回调函数,然后在其中处理错误。当然,如果在运行过程中,抛出错误,也会被
catch
捕获。Promise.prototype.finally()
Promise.prototype.finally()
方法不管Promise
对象最后状态如何,都会进行执行。Promise 类方法
Promise.all()
Promise.all()
方法可以将多个Promise
实例,包装成一个新的Promise
实例。Promise
中,其中一个状态不是fulfilled
,p 的结果就不会是fulfilled
rejected
,此时第一个被reject
的实例的返回值,会被传递为promise
的回调函数。Promise.race()
Promise.race()
方法同样是将多个实例包装为一个新的Promise
实例。Promise
时,哪一个率先改变状态,promise
的状态就跟着哪个改变。我们在第一个使用了
setTimeout
,进行延迟,所以会是第二个的状态先改变,输出第二个的值。Promsie.allSettled()
Promise.allSettled()
方法,用来确定一组异步操作是否都结束了。 数组的每个成员都是一个 Promise 对象,并返回一个新的Promise
对象,只有数组中的Promsie
对象状态都发生改变时,返回的Promise
对象才发生改变。 返回的值会接收到一个数组作为参数,该数组的每一个成员对应前面数组的每个Promise
对象。数组成员对象的
status
属性的值只可能是fulfilled
或rejected
,用来区别异步操作结果是成功(fulfilled
)还是失败(rejected
)。 如果是成功是会有value
属性,记录成功值,如果失败,会有reason
属性,记录失败原因。Promise.any()
Promise.any()
方法,将一组Promise
实例作为参数,包装成一个新的Promise
实例并返回。fulfilled
状态,新实例就会被包装成fulfilled
状态rejected
状态,包装实例就会变成rejected
状态Promise.resolve()
Promise.resolve()
方法有四种情况。Promise
时,不做任何修改,直接返回这个实例。thenable
对象thenable
对象就是有then
方法的对象。Promise.resolve()
方法会将thenable
转为Promise
对象,并立即执行其中的then
方法。then
的对象,或不是对象的参数Promise.resolve()
方法返回一个心的 Promise 对象,状态转为resolved
。Promise.resolve()
方法可以不传参数,直接返回一个resolved
状态的Promise
对象。 所以在希望得到一个Promise
对象,直接调用比较该方法方便。注意,立即
resolve()
的Promise
对象,是在本轮[事件循环(event loop)]()的结束时执行。Promise.reject()
Promise.reject()
方法返回一个新Promise
实例,该实例状态为rejected
。