博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于Promise
阅读量:7165 次
发布时间:2019-06-29

本文共 6207 字,大约阅读时间需要 20 分钟。

Promise是一种异步编程的解决方案,相比传统回调函数更合理.

1.Promise立即执行性

let p = new Promise((resolve, reject) => {    console.log('立即执行!');    resolve('返回成功!')});console.log('promise后执行!');p.then(value => {    console.log(value)});

控制台输出:

"立即执行!""promise后执行!""返回成功!"

Promise对象表示未来发生的事件,在创建promise时,作为promise参数传入的函数是会被立即执行的,只是其中执行的代码可以是异步代码.有些人会认为,当promise对象调用then方法时,promise接受的函数才会执行,这是错误的.所以,代码中立即执行!先于promise后执行!输出.

2.Promise的三种状态.

let p1 = new Promise((reslove, reject) => {    reslove(1);});let p2 = new Promise((reslove, reject) => {    setTimeout(() => {        reslove(2);    }, 500);});let p3 = new Promise((reslove, reject) => {    setTimeout(() => {        reject(3);    }, 500);});console.log(p1);console.log(p2);console.log(p3);setTimeout(() => {    console.log(p2);}, 1000);setTimeout(() => {    console.log(p3);}, 1000);p1.then(value => {    console.log(value);});p2.then(value => {    console.log(value);});p3.catch(err => {    console.log(err);});

控制台输出:

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}123Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}

Promise内部实现是一个状态机.Promise有三种状态: pending,resolved,rejected.当Promise刚创建完成时,处于pending状态;当Promise中的函数参数执行了resolve后,Promise由pending状态变成resloved状态;如果Promise的函数参数中执行的是reject方法,那么Promise会有pending状态变成rejected状态.

3.Promise状态不可逆性.

let p1 = new Promise((reslove, reject) => {    reslove('成功1!');    reslove('成功2!');});let p2 = new Promise((reslove, reject) => {    reslove('成功!');    reject('失败!');});p1.then(value => {    console.log(value);});p2.then(value => {    console.log(value);});

控制台输出:

"成功1!""成功!"

Promise的状态一旦变成resolved或rejected时,Promise的状态和值就固定下来了,无论后续再怎么调用reslove或是reject方法,都不能改变它的状态和值.所以,p1中reslove('成功2!')并不能将p1的值更改为成功2!,p2中reject('失败!')也不能将p2的状态由resolved改变为rejected.

4.链式调用.

let p = new Promise((resolve, reject) => {    resolve(1);});p.then(value => {    console.log(value);    return value * 2;}).then(value => {    console.log(value);}).then(value => {    console.log(value);    return Promise.resolve('resolve');}).then(value => {    console.log(value);    return Promise.reject('reject');}).then(value => {    console.log(`resolve: ${value}`);}, err => {    console.log(`reject: ${err}`);})

控制台输出:

12undefined"resolve""reject: reject"

Promise对象的then方法返回一个新的Promise对象,所以可以通过链式调用then方法.then方法接受两个函数作为参数,第一个参数是Promise执行成功时的回调,第二个参数是Promise执行失败时的回调.两个函数只会有一个被调用,函数返回值将用作创建then返回的Promise对象.这两个参数的返回值可以是下面三种情况的一种:

①:return一个同步的值,或者undefined(当没有返回一个有效值时,默认返回undefined),then方法将返回一个resloved状态的Promise对象,Promise对象的值就是这个返回值.②:return另一个Promise,then方法将根据这个Promise的状态和值创建一个新的Promise对象返回.③:throw一个同步异常,then方法将返回一个rejected状态的Promise,值是该异常.

根据以上分析,代码中的第一个then会返回一个值为2(1 * 2),状态为resolved的Promise对象,于第二个then输出的值为2.第二个then中没有返回值,因此将返回默认的undefined,于是在第三个then中输出的undefined.第三个then和第四个then中分别返回一个状态是resloved的Promise和一个状态是rejected的Promise,依次由第四个then中的成功回调函数和第五个then中的失败回调函数处理.

5.Promise then()回调异步性.

let p = new Promise((resolve, reject) => {    resolve('成功!');});p.then(value => {    console.log(value);});console.log("谁先执行?")

控制台输出:

"谁先执行?""成功!"

Promise接受的函数参数是同步执行的,但是then方法中的回调函数则是异步的,因此,成功!会在后面输出.

6.Promise中的异常.

let p1 = new Promise((resolve, reject) => {    foo.bar();    resolve(1);});p1.then(value => {    console.log(`p1 then value: ${value}`);}, err => {    console.log(`p1 then err: ${err}`);}).then(value => {    console.log(`p1 then then value: ${value}`);}, err => {    console.log(`p1 then then err: ${err}`);});let p2 = new Promise((resolve, reject) => {    resolve(2);});p2.then(value => {    console.log(`p2 then value: ${value}`);    foo.bar();}, err => {    console.log(`p2 then err: ${err}`);}).then(value => {    console.log(`p2 then then value: ${value}`);}, err => {    console.log(`p2 then then err: ${err}`);    return 1;}).then(value => {    console.log(`p2 then then then value: ${value}`);}, err => {    console.log(`p2 then then then err: ${err}`);});

控制台输出:

p1 then err: ReferenceError: foo is not definedp2 then value: 2p1 then then value: undefinedp2 then then err: ReferenceError: foo is not definedp2 then then then value: 1

Promise中的异常由then参数中的第二个回调函数(Promise执行失败的回调)处理,异常信息将作为Promise的值.异常一旦得到处理,then返回后续的Promise对象将恢复正常,并会被Promise执行成功的回调函数处理.另外,需要注意p1,p2多级then的回调函数是交替执行的,这正是由Promise then回调的异步性决定的.

7.Promise.reslove().

let p1 = Promise.resolve(1);let p2 = Promise.resolve(p1);let p3 = new Promise((resolve, reject) => {    resolve(1);});let p4 = new Promise((resolve, reject) => {    resolve(p1);});console.log(p1 === p2);console.log(p1 === p3);console.log(p1 === p4);console.log(p3 === p4);p4.then(value => {    console.log(`p4=${value}`)});p2.then(value => {    console.log(`p2=${value}`)});p1.then(value => {    console.log(`p1=${value}`)});

控制台输出:

truefalsefalsefalsep2=1p1=1p4=1

Promise.resolve(...) 可以接受一个值或者是一个Promise对象作为参数.当参数是普通值时,它返回一个resolved状态的Promise对象,对象的值就是这个参数;当参数是一个Promise对象时,它直接返回这个Promise参数.所以p1===p2.但通过new创建的Promise对象都是一个新的对象,所以后面三个比较结果都是false.另外,为什么p4的then最先调用,但是在控制台上是最后输出结果的呢?因为p4中resolve接受的参数是一个Promise对象p1,reslove会对p1进行解析,获取p1的状态和值,但是这个过程是异步的.

8.resolve v reject.

let p1 = new Promise((resolve, reject) => {    resolve(Promise.resolve('resolve'));});let p2 = new Promise((resolve, reject) => {    resolve(Promise.reject('reject'));});let p3 = new Promise((resolve, reject) => {    reject(Promise.resolve('resolve'));});p1.then(value => {    console.log(`p1 fulfilled: ${value}`);}, err => {    console.log(`p1 rejected: ${err}`);});p2.then(value => {    console.log(`p2 fulfilled: ${value}`);}, err => {    console.log(`p2 rejected: ${err}`);});p3.then(value => {    console.log(`p3 fulfilled: ${value}`);}, err => {    console.log(`p3 rejected: ${err}`);});

控制台输出:

p3 rejected: [object Promise]p1 fulfilled: resolvep2 rejected: reject

Promise回调函数中的第一个参数resolve,会对Promise执行解析,即resolve的参数是Promise对象时,resolve会解析获取这个Promise对象的状态和值,但这个过程是异步的.p1解析后,获取到Promise对象的状态是resolved,因此第一个回调被执行也就是获取value的回调;p2解析后,获取到Promise对象的状态rejected,因此rejected回调执行.但Promise回调函数中的第二个参数reject不具备解析能力,reject的参数会直接传递给then方法中的rejected回调,因此,即使p3 reject接受了一个resolved状态的Promise,then方法中调用的依然是rejected,并且参数就是reject接受到的Promise对象.

转载地址:http://rpqwm.baihongyu.com/

你可能感兴趣的文章
OrbitDB-Peer 2 Peer Database using CRDTs
查看>>
全屏状态下层级问题(z-index)
查看>>
Using a SecureCRT 链接远程主机
查看>>
python写的好的博客链接
查看>>
linux shell wait process finished,等待线程执行结束
查看>>
MySQL内存表的特性与使用介绍
查看>>
男人帮,帮男人找爱情
查看>>
linux添加HIVE环境变量
查看>>
Secure Delivery Center快速入门指南(二):交付软件包
查看>>
MyEclipse Spring开发教程:使用基本的Spring功能(三)
查看>>
算法训练 未名湖边的烦恼
查看>>
数据库的备份和恢复
查看>>
2019假期作业(一)
查看>>
1.登陆一下好吗??
查看>>
java集合
查看>>
java计算最大回文字串
查看>>
中国区优化的Docker安装脚本
查看>>
jenkins安装
查看>>
百度:地震姜常宏,求传播?!!
查看>>
Angular2官网项目 (4)--路由
查看>>