当前位置: 首页 > ops >正文

阮一峰ES6精缩——Promise对象

Promise对象

1. Promise的含义

  • 它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
  • 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
  • Promise对象有以下两个特点。
    • Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
    • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
  • Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
  • 如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择

3. Promise.prototype.then()

then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。
then方法返回一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

getJSON("/posts.json").then(function(json) {return json.post;
}).then(function(post) {// ...
});
上面的代码使用then方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

Promise.prototype.catch()

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
另外,then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。

如果 Promise 状态已经变成resolved,再抛出错误是无效的。

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

上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。

6. Promise.all()

  • 将多个 Promise 实例,包装成一个新的 Promise 实例。
  • Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

注意,如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。

const p1 = new Promise((resolve, reject) => {resolve('hello');
})
.then(result => result)
.catch(e => e);const p2 = new Promise((resolve, reject) => {throw new Error('报错了');
})
.then(result => result)
.catch(e => e);Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

上面代码中,p1会resolved,p2首先会rejected,但是p2有自己的catch方法,该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。

如果p2没有自己的catch方法,就会调用Promise.all()的catch方法。

const p1 = new Promise((resolve, reject) => {resolve('hello');
})
.then(result => result);const p2 = new Promise((resolve, reject) => {throw new Error('报错了');
})
.then(result => result);Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// Error: 报错了

7. Promise.race()

  • 同样是将多个 Promise 实例,包装成一个新的 Promise 实例。与Promise.all()方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve()方法,将参数转为 Promise 实例,再进一步处理。

8. Promise.allSettled()

有时候,我们希望等到一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作。但是,现有的 Promise 方法很难实现这个要求。

  • Promise.all()方法只适合所有异步操作都成功的情况,如果有一个操作失败,就无法满足要求。

个人理解:Promise.all() p1、p2、p3 全执行完或其中一个rejected才向下执行,而Promise.race()是其中一个fulfilled或者rejected直接向下执行。Promise.allSettled() 无论如何等待全部执行完再往下。Promise.any() 是任意一个fulfilled就fulfilled,全部rejected才rejected。

http://www.xdnf.cn/news/11329.html

相关文章:

  • 扫码登录操作过程
  • 19-1 burpsuite模块介绍之repeater
  • 再生龙linux 系统运行,使用Clonezilla(再生龙)克隆Linux系统
  • GNOME 与 KDE:到底选择哪个 Linux 桌面环境
  • Oracle的PDB和CDB
  • 使用NAGA分析雀魂牌谱
  • 消息中间件的概念
  • Adhesive框架系列文章--Mongodb数据服务模块实现(上)
  • javascript:void(0) 含义
  • 网络知识点之-详解robots协议
  • 【Oracle】CBO优化详解
  • 服务等级目标SLO概述
  • 恶意网站的攻与妨
  • Java在云原生的破局利器——AOT(JIT与AOT)
  • 【Java开发语言 00】环境搭建(配置java环境+‘javac’不是内部或外部命令,也不是可运行的程序+安装idea+idea基本用法+新建项目+在新项目的src路径下新建包和类+基础调试+路径)
  • UPX的使用
  • bootstrap4 左侧导航栏 优秀 大气_7个冷门行业导航网站,冷门行业小伙伴的终极关怀(值得收藏)...
  • 11111111111111
  • Linux解压命令大全
  • IOS Xcode下载教程(各版本)
  • 如何在csdn免费下载资料?
  • 20. 【Linux教程】emacs 编辑器
  • 5款常用的漏洞扫描工具,网安人员不能错过(非常详细)零基础入门到精通,收藏这一篇就够了
  • 最新超详细VMware虚拟机安装完整教程
  • flv.js的用法与说明总结
  • 永恒之蓝漏洞复现
  • 推荐8部好看的抗日电视剧
  • NDK学习之路-Linux基础篇
  • C语言为内存分配空间(代码段、数据段、bss段、存储类、变量的生命周期)_c语言全局字符串在代码段吗
  • 软件测试报告示例模板