博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(JS基础)Promise 对象
阅读量:7021 次
发布时间:2019-06-28

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

概述

Promise对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的

Promise对象有三种状态pending(初始状态)、fulfilled(成功状态)、rejected(失败状态)。

Promise对象的状态一旦由pending变为fulfilledrejected无法再更改

Promise对象的状态变为fulfilled后,通过then()方法执行回调函数;状态变为rejected后,通过catch()方法执行回调函数。

在 ES2018 中引入了finally(),表示该Promise执行结束后(无论是"then"还是"catch"导致的结束)都会执行传入finally方法的回调函数,回调函数无参数。

简单示例

创建

通过new运算符可以创建Promise实例,唯一参数是带有 resolvereject两个参数的 executor函数resolvereject函数被调用时,分别将Promise的状态改为fulfilled(完成)或rejected(失败),两个函数都接受一个参数,作为成功(或失败)的信息传递给对应的处理方法(thencatch)。

let p = new Promise((resolve, reject) => {  setTimeout(() => {    if (Math.random() > 0.5) {      resolve('resolve');    } else {      reject('reject');    }  }, 1000);});复制代码

上述例子中,1 秒后随机把Promise对象的状态改为fulfilled(完成)或rejected(失败)。

处理

被创建的Promise对象会立即执行executor函数,如果我们还需要在该异步函数结束后再做点什么,就需要调用Promise对象的then()catch()finally()方法。(三个方法都会返回一个新的Promise对象,因此能使用"链式操作")

接上例子:

p.then(res => {  console.log(res);   // 'resolve'}).catch(err => {  console.log(err);   // 'reject'}).finally(()=>{  console.log('finally');    // 必定执行});复制代码

可以看出,then()catch()方法传入的是一个回调函数,该回调函数有唯一参数,对应的是resolvereject函数传入的参数。finally()同样是传入一个对调函数,不同的是该回调函数无参数。

几种场景

场景1:多个Promise需要依次执行。(Promise.prototype.then()可以传入另一个Promise对象

const promise1 = new Promise(...);const promise2 = new Promise(...);const promise3 = new Promise(...);// promise1成功执行后再执行promise2,再是promise3promise1.then(promise2).then(promise3);复制代码

场景2:多个Promise需要都成功。(静态方法:Promise.all()

const promise1 = new Promise(...);const promise2 = new Promise(...);const promise3 = new Promise(...);// promise1/2/3 均成功后再执行 then ( 其中一个失败也不会执行 then )Promise.all([promise1, promise2, promise3]).then(callback(){...});复制代码

场景3:多个Promise只需要其中一个成功。(静态方法:Promise.race()

const promise1 = new Promise(...);const promise2 = new Promise(...);const promise3 = new Promise(...);// promise1/2/3 任意一个成功后执行 thenPromise.race([promise1, promise2, promise3]).then(callback(){...})复制代码

Promise.resolve()

Promise.resolve()用于生成一个状态为fulfilledPromise对象。其参数与.prototype.resolve()一致。

let p1 = Promise.resolve('resolve');// 等效如下代码let p2 = new Promise((resolve, reject) => {  resolve('resolve');});复制代码

Promise.reject()

Promise.reject()用于生成一个状态为rejectedPromise对象。其参数与.prototype.reject()一致。

let p1 = Promise.reject('resolve');// 等效如下代码let p2 = new Promise((resolve, reject) => {  reject('resolve');});复制代码

继续深入了解

then() 的第二个参数

其实上面的介绍中,完全没有提及then()的第二个参数,因为其作用与catch()方法一致。看下面例子:

let p = new Promise((resolve, reject) => {  reject('reject');})p.then(res => { }, err => {  console.log(err);     // 'reject'});p.catch(err => {  console.log(err);     // 'reject'});复制代码

不传参的 then()/catch()/finally()

then()/catch()/finally()不传入参数,都会返回与原Promise对象相同(但不相等)的新Promise对象。看如下例子:

// 不传参的"then"let p1 = Promise.resolve('resolve');let p2 = p1.then();p2.then(res => {  console.log(res);       // 'resolve'});console.log(p1 === p2);   // false// 不传参的"catch"let p3 = Promise.reject('reject');let p4 = p3.catch();p4.catch(res => {  console.log(res);       // 'reject'});console.log(p3 === p4);   // false// 不传参的"finally"let p5 = Promise.resolve('resolve');let p6 = p5.finally();p6.then(res => {  console.log(res);       // 'resolve'});console.log(p5 === p6);   // false复制代码

then()/catch()/finally() 的参数是带返回值的回调函数

then()catch()的参数是有返回值的回调函数Athen()catch()返回一个状态为fulfilledPromise对象。新Promise对象的then()方法的回调函数的参数就是回调函数A的返回值。

注意,状态为rejectPromise对象在then()的第一个对调函数返回会导致报错。

注意,finally()的对调函数"return"并不会影响新的Promise对象的then()catch()方法的回调函数的参数值。

如果觉得文字描述有点绕,看下面例子:

// 'resolve'状态被处理后的'return'Promise.resolve('resolve').then(() => {  return 'return1'}).then(res => {  console.log(res)});   // 'return1'// 'reject'状态被处理后的'return'Promise.reject('resolve').catch(() => {  return 'return2'}).catch(err => {  console.log('catch:', err)}).then(res => {  console.log('then:', res)});   // 'then: return2'// 'finally'的'return'只会返回与原promise相同的对象Promise.resolve('resolve').finally(() => {  return 'return3'}).then(res => {  console.log(res)});   // 'resolve'// 'reject'状态未被处理的'return'Promise.reject('reject').then(() => {  return 'return4'}).then(res => {  console.log(res);});   // 报错!!复制代码

.resolve() 的参数

resolve()(包括Promise.reject()Promise.prototype.reject())除了上面介绍的用法,还能传入thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定。

注意,thenablethen()方法只有传入唯一一个回调函数才会被执行,其他参数会被忽略。

看如下例子:

let thenable = {  then(cb1, cb2) {    cb1('cb1');    cb2('cb2');  }}// Promise.resolve()Promise.resolve(thenable).then(  res1 => {    console.log(res1);  // 'cb1'  },  res2 => {    console.log(res2);  // 不会执行  }).catch(err => {  console.log(err);     // 不会执行});// Promise.prototype.resolve()new Promise((resolve, reject) => {  resolve(thenable);}).then(res => {  console.log(res);     // 'cb1'});复制代码

转载于:https://juejin.im/post/5cf096d0e51d4577790c1c34

你可能感兴趣的文章
Jenkins的安装和使用(Centos7)
查看>>
Red Hat Linux的学习
查看>>
java关于安卓,苹果输入表情数据库处理
查看>>
oracle与db2分区的区别
查看>>
如何快速把一个11g数据库插入到12c cdb中去?
查看>>
缓存架构设计细节二三事
查看>>
mybatis链接数据库 返回自增主键
查看>>
SpringBoot简化部署
查看>>
yml使用
查看>>
3.04-Miniui总结(一)
查看>>
Hadoop-工作流图解
查看>>
js基础 局部变量和全局变量 作用域链 形参是局部变量
查看>>
nexus
查看>>
springboot 使用jsp
查看>>
Tomcat_JDK部署、zrlog安装和nginx代理Tomcat
查看>>
DRDS到MaxCompute(原ODPS)数据归档性能优化测试
查看>>
11.22 访问日志不记录静态文件 11.23 访问日志切割 11.24 静态元素过期时间
查看>>
shell脚本中的逻辑判断,文件目录属性判断, if特殊用法,case判断
查看>>
【JavaWeb】权限管理系统
查看>>
火币网程显峰:区块链技术风险到底是些什么鬼?
查看>>