当前位置:首页 > 技术分析 > 正文内容

JavaScript(ES6) Promise对象学习

ruisui885个月前 (02-03)技术分析27

JavaScript语言标准第6版,即ECMAScript 6中新增了Promise规范,该来源于Promises/A+社区。在JavaScript中已经早有Promise的实现,在Node.js中也有多个实现了Promise规范的 npm 模块。ECMAScript 6将其写进了语言标准,对Promise用法进行了规范,并提供了原生的Promise对象,在Firefox和Chrome最新版本的浏览器上,己经提供了对Promise的支持。本文主要以ES6 Promises为基础的,介绍Promise对象的相关知识。

1. 了解Promise

1.1 JavaScript异步处理

JavaScript是一种采用事件驱动的脚本语言,在JavaScript中,处理异步都是使用callback的方式,例如:Node.js就是基于回调函数机制进行异步处理的。随着JavaScript的使用日益广泛,其开发模式也日渐成熟,随之也就产生了两种模块管理规范:AMD (Asynchronous Module Definition)规范和CMD (Common Module Definition,即:CommonJS)规范,在CommonJS中,就包括了用于异步处理的Promise规范。

示例,jQuery的GET请求中异步处理:

1.2 什么是Promise

Promise出现在的并不晚,其最初是在 E语言中被提出,而ECMAScript 6中的Promise规范来源于Promises/A+社区。

Promise是一个用于异步处理对象,其中包含了对异步进行各种操作的组件。Promise把JavaScript中的异步处理对象和处理规则进行了规范化,并按照统一的接口来编写,使用规定方法之外的写法会出现错误。使用Promise规范处理异步编程,相对比较简单和易于理解。

示例,使用Promise进行异步处理:

以上代码,注册Promise对象执行成功时和失败时相应的回调函数。与回调函数处理机制不同的是,使用Promise进行处理的时候,必须按照接口规定的方法编写处理代码,即:除promise对象规定(如上面代码的then和catch方法)以外的方法都是不可以使用的, 不能像回调函数方式那样可以自己自由的定义回调函数的参数,而必须按照固定、统一的编程方式来编写代码。

基于Promise规范,为异步处理统一了异步处理接口, 这样就形成了基于接口形成了不同的异步处理模式。因此,可以将复杂的异步处理模式化、简单化。

1.3 Promise/A+规范

由于ECMAScript 6中的Promise规范来源于Promise/A+规范,了解Promise/A+规范有助更好的学习和理解Promise。下面是对Promise/A+规范的简单介绍:

  • 一个promise有一到三种状态:pending(等待)、fulfilled或resolved(成功-已完成)、rejected(失败-已拒绝)

  • 一个promise的状态只可能从等待到完成或者拒绝状态,不能逆向转换,同时完成和拒绝状态不能相互转换

  • promise实例必须实现then方法,而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致

  • then方法接受两个参数:第一个参数是成功时的回调,在promise由等待养成转换到完成态时调用。另一个是失败时的回调,在promise由等待状态转换到拒绝状态时调用。同时,then可以接受另一个promise传入,也接受一个类似then的对象或方法,即:thenable对象

2. Promise对象简

在ECMAScript 6 Promise规范中,Promise对象包括三部分:构造函数、实例方法、静态方法。

2.1 构造函数:Promise

要创建一个Promise对象实例,需要调用构造函数Promise并使用new关键字来创建,示例如下:

Promise构造函数接受一个函数作为传入参数,该函数包含两个参数:resolve、reject,这两个参数是两个回调函数,分别用于执行成功和执行失败时的回调。

  • resolve函数:Promise对象状态由pending(等待)状态转换为fulfilled(成功)状态时的回调

  • reject函数:Promise对象状态由pending(等待)状态转换为rejected(失败)状态时的回调

2.2 Promise对象的实例方法

在JavaScript中,实例方法是指定在原型链prototype上的方法,Promise对象中有两个实列方法(原型方法):Promise.prototype.then、Promise.prototype.catch。

通过new创建Promise对象实例后,为了设置其值在resolve(成功) / reject(失败)时调用的回调函数,可以使用promise.then()实例方法进行设置,设置格式为:

  • promise.then(onFulfilled, onRejected)

    • resolve(成功)时,onFulfilled方法会被调用

    • reject(失败)时,onRejected方法会被调用

在promise.then方法中,onFulfilled、onRejected 两个都是可选参数,如果只用于对异常的处理,可以使用promise.then(undefined, onRejected)方式(即:只指定reject函数)。只处理异常时,也可以使用promise.catch方法,方法使用格式如下:

  • promise.catch(onRejected)

为了提高代码的可读性,我们可以使用promise.then处理操作成功的情况,使用promise.catch处理操作失败的情况,示例如下:

2.3 Promise对象的静态方法

静态方法又称为类方法,是指不需要实例化就可以使用的方法。在Promise对象还有一些静态方法,这些方法都是一些对Promise进行操作的辅助方法。

2.3.1 Promise.all()方法

  • Promise.all(promiseArray)

  • 参数:promiseArray,是一个promise实例数组

  • 方法作用:将多个Promise实例包装,生成并返回一个新的promise实例。参数传递promise数组中所有的promise实例都变为resolve的时候,该方法才会返回, 新创建的promise则会使用这些promise的值。如果参数中的任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象

2.3.2 Promise.race()方法

  • Promise.race(promiseArray)

  • 参数:promiseArray,是一个promise实例数组

  • 方法作用:将多个Promise实例包装,生成并返回一个新的promise实例。参数promise数组中的任何一个promise实例如果变为resolve或者reject的话,该函数就会返回,并使用这个promise实例的值进行resolve或者reject。

2.3.3 Promise.resolve()方法

  • Promise.resolve(obj)

  • 参数:obj,是一个待转换为promise的对象,其可能是以下3种形式:

    • 为promise实例是,原样返回

    • 为thenable对象是,将对象转换为promise对象并返回,这个对象具有then方法

    • 其它类型(包括JavaScript对或null等),返回一个将该对象作为值的新promise对象

  • 方法作用:将对象转为promise实例。参数promise数组中的任何一个promise实例如果变为resolve或者reject的话,该函数就会返回,并使用这个promise实例的值进行resolve或者reject。

2.3.4 Promise.reject()方法

  • Promise.reject(obj)

  • 参数:obj,是一个待转换为promise的对象

  • 方法作用:将对象转为promise实例,该实例的状态为rejected。

来自:http://itbiu.com

QQ交流群:564850876

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/710.html

分享给朋友:

“JavaScript(ES6) Promise对象学习” 的相关文章

身体越柔软越好?刻苦拉伸可能反而不健康 | 果断练

坐下伸直膝盖,双手用力向前伸,再用力……比昨天前进了一厘米,又进步了! 这么努力地拉伸,每个人都有自己的目标,也许是身体健康、线条柔美、放松肌肉、体测满分,也可能为了随时劈个叉,享受一片惊呼。 不过,身体柔软,可以享受到灵活的福利,也可能付出不稳定的代价,并不是越刻苦拉伸越好。太硬或者太软,都不安全...

USB电池充电基础:应急指南

USB为便携设备供电与其串行通信功能一样,已经成为一种标准应用。如今,USB 供电已经扩展到电池充电、交流适配器及其它供电形式的应用。应用的普及带来的一个显著效果是便携设备的充电和供电可以互换插头和适配器。因此,相对于过去每种装置都采用专用适配器的架构相比,目前的解决方案允许采用多种电源进行充电。毋...

JavaScript数组操作:掌握常用方法,提升开发效率

JavaScript数组操作:从增删改查到高级应用本文深入解析JavaScript中常用的数组方法,包括push、unshift、pop、shift、map、filter、reverse、at 和 slice。通过详细的例子和应用场景,帮助开发者快速掌握这些方法,提升代码效率和可读性。开篇点题作为J...

在vue项目中封装WebSockets请求

在Vue项目中封装WebSocket请求包括以下步骤:1. 安装WebSocket库:首先,导入WebSocket库,例如`vue-native-websocket`或`socket.io-client`。根据项目需求选择适当的库,并根据官方文档进行安装和配置。2. 创建WebSocket服务:在V...

能者多劳!让NVMe固态硬盘做系统盘的同时,加速SATA数据盘

不知不觉当中,固态硬盘已经取代机械硬盘成为主流。越来越多的玩家已经淘汰机械盘,使用NVMe+SATA的固态硬盘高低搭配。既然是高低搭配,就一定会有性能差距,是否能从NVMe固态硬盘中划分出一小部分空间来给SATA固态硬盘加速,实现更好地整机性能呢?答案是肯定的,而且这一功能早已隐藏在英特尔Z170、...

52、Vue 怎么实现跨域(必会)

1、什么是跨域跨域指浏览器不允许当前页面的所在的源去请求另一个源的数据。源指协议,端口,域名。只要这个 3 个中有一个不同就是跨域2、使用 vue-cli 脚手架搭建项目时 proxyTable 解决跨域问题,打开 config/index.js,在 proxyTable 中添写如下代码:proxy...