详解ES6 Promise的生命周期和创建

一:Promise的概念

Promise的中文意思是‘承诺',什么叫承诺?承诺就是现在没有发生,在将来的某个时刻一定会发生的事情。
放在编程语言的环境下,Promise就是异步事件的结果的占位符。我们不用去管异步事件的结果什么时候来,只需要关心异步事件的结果产生的时候,你想要做什么就对了。

二:Promise的生命周期

异步事件不是立即执行程序,它的结果可能要在动作发生后一段时间才到,所以它有个生命周期。例如用电饭锅煮米饭,从【米下锅开始定时】到【定时结束】,这是煮米饭的生命周期。
一个Promise的生命周期主要有2个阶段:

1: unsettled(pending) 处理过程中 -> 米饭定时开始到定时结束这段期间
2: settled (fulfilled或者rejected) 处理完 -> 米饭定时结束状态

我们看到settled阶段会出现两个可能的状态fulfilled或者rejected,它们分别是什么意思呢:

1: fulfilled Promise操作完成的结果为成功 -> 煮米饭水的比例合适,饭熟了,成功
2: rejected Promise操作完成的结果为失败 -> 煮米饭水放少了,饭是夹生的,失败

Promise内部的属性PromiseState被用来表示Promise的3种状态:pending,fulfilled 和 rejected。但是我们无法读取到这三个状态,而是通过Promise提供的接口方法来书写对应的处理程序,后面会讲到。

三:如何让创建一个Promise

相信前面通过对比煮饭这个过程,你已经对Promise的概念和生命周期有了一定的体会,接下来我们就看看如何真正第创建一个Promise(如何煮米饭)。

声明:因为Promise有未完成的Promise和已完成的Promise不同类型,本篇我们只讨论未完成的Promise。已完成的Promise后面会讲,目前来说你不必关心,就当世界上没有这个东西。

通过Promise构造函数,可以创建一个Promise。构造函数只有一个参数:一个函数,我们叫它执行器(executor)函数。你可以理解为煮饭用的电饭煲。

既然执行器(executor)函数也是一个函数,那它也有参数。对,它有2个参数:

1: resolve() 执行器(executor)函数成功时的处理函数
2: reject() 执行器(executor)函数失败时的处理函数

我们用一段代码来解释一下:

let executor = function (resolve, reject) {};
let promise = new Promise(executor);

通过上面的代码示例,应该就能很清楚创建一个Promise的语法解构是怎样的了。接下来我们用一个在Node.js中读取文件的例子来演示:

let executor = function (resolve, reject) {
  let fs = require('fs');
  fs.readFile('data.txt', {encoding: 'utf8'}, function (error, content) {
    if (error) {
      reject(error); //在异步行为失败时,调用reject()方法
      return;
    }
    resolve(content); //在异步行为成功时,调用resolve()方法

  });
};
let promise = new Promise(executor);

解释一下上面的代码:

1: 创建Promise,包裹异步程序

Promise本身并不执行任何真正的异步程序。我们只是把异步程序包裹在一个Promise里面,这样做的目的其实是想把异步处理程序的结果给Promise,稍后再利用Promise提供的接口函数(then()或者catch())来对结果进行处理。

2: 我们在Promise的executor函数里调用真正的异步操作函数。

我们在executor函数里调用fs.readFile( )函数。fs.readFile( )函数本身是一个异步行为,其方法的第三个参数为一个回调函数,用来接收文件读取的结果(失败时候的error和成功时候的content)。

3: 把异步程序的结果给Promise

我们在fs.readFile( )的回调函数里,在文件读取成功时调用resolve( )方法,失败的时候调用reject( )方法,把成功或者失败的结果通过2个函数的参数传入,为Promise在fulfilled或者rejected两种状态时提供数据。

四:编写Promise结果处理程序

前面我们已经了解到了怎么把一个异步处理事件包裹在一个Promise里面,并且通过resolve()和reject()把异步处理事件的结果传递的过程。终于来到了最后一步:使用结果数据(对比现实生活,你也可以理解为这一步叫做:验证承诺)。
Promise提供2个方法来处理结果: Promise.prototype.then() 和 Promise.prototype.catch()。我们分别来看一下二者的功能:

1:Promise.prototype.then()

then()方法接收2个函数类行的参数:

1: 第一个参数为Promise在fulfilled状态(成功状态)时的回调方法
2: 第一个参数为Promise在rejected状态(失败状态)时的回调方法
我们以之前的读取文件为例子,看一下then()方法的使用:

let executor = function (resolve, reject) {
  let fs = require('fs');
  fs.readFile('data.txt', {encoding: 'utf8'}, function (error, content) {
    if (error) {
      reject(error); //在异步行为成功时,调用reject()方法
      return;
    }
    resolve(content); //在异步行为失败时,调用resolve()方法

  });
};
let promise = new Promise(executor);

//处理成功和失败的情况
promise.then(function (content) {
  console.log(content);

}, function (error) {
  console.log(error)
});

这两个回调函数的参数也就是之前异步处理的结果数据。第一个函数的参数对应resolve()的参数content,第二个回调函数对应reject()的参数error。这样我们也就能在这2个回调函数里面拿到数据,从而根据你的业务需求编写对应的结果处理程序。

需要说明的是,这两个回调函数参数都不是必须的,并不强制要求你都要处理。下面的代码里,列觉了某2种结果处理程序,语法上都是合法的。只是正常的需求下,我们一般还是需要对成功和失败都要处理。

 //只处理成功的情况
promise.then(function (content) {
  console.log(content);

});
//只处理失败的情况
promise.then(null, function (error) {
  console.log(error)
});

2: Promise.prototype.catch()

catch()方法只有一个参数:一个只处理rejected状态的回调函数。可能会有人疑问,then()已经可以同时处理2个状态,为什么还需要catch()方法?

原因在于前面我们提到的,在then()方法里,并不强制要求你提供处理rejected的回调函数。Promise有个特性:如果你没有添加rejected处理函数,那所有的失败会被自动忽略。

可能会有些开发者只关心成功状态,而忘了提供rejected处理函数,从而给整个程序埋下隐患,这样会造成很不好的用户体验。而catch()方法就是一个明确地处理rejected的方法,而不像在then()里面,因为是非必须参数而让人很容易忽略。

背景说了那么多,我们看看catch()怎么用:

promise.catch(function (error) {
  console.log(error)
})

其实用法很简单,它其实等价于是有reject处理函数的then():

promise.then(null, function (error) {
  console.log(error)
});

没有语法要求一个完整的Promise处理程序必须要有catch()方法。如果你没有使用catch()的习惯,最好总是不要忘记在使用then()的时候添加reject处理函数。

或者,如果你偶尔会忘记在then()里添加reject处理函数,那么记得使用catch()来为你做最安全的保障。

以上,就是关于Promise的基本概念和使用。在平常的开发中,Promise的使用还是非常频繁的,也很好用,所以我认为掌握Promise是一个必须的功课。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ES6关于Promise的用法详解

    Node的产生,大大推动了Javascript这门语言在服务端的发展,使得前端人员可以以很低的门槛转向后端开发. 当然,这并不代表迸发成了全栈.全栈的技能很集中,绝不仅仅是前端会写一些HTML和一些交互,后台熟悉数据库的增删查改. 想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性.如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行,这样按照Node的一般执行规律,要实现有序的异步操作,通常是一层加

  • 让你彻底掌握es6 Promise的八段代码

    前言 新的ES6中引入了promise的概念,目的是让回调更为优雅.层层嵌套的回调会让javascript失去美感和可读性,同时javascript也推荐采用链式的方式去书写函数调用.于是Promise就应运而生.本文将通过八段代码让大家彻底的掌握Promise,下面话不多说,来一起看看详细的介绍: 1.Promise的立即执行性 var p = new Promise(function(resolve, reject){ console.log("create a promise")

  • ES6 Promise对象的含义和基本用法分析

    本文实例讲述了ES6 Promise对象的含义和基本用法.分享给大家供大家参考,具体如下: 1.Promise的含义 Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件 (通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息. Promise对象有以下2个特点: 1.对象的状态不受外界影响.Promise对象代表一个异步操作,有三种状态:Pend

  • 深入解析ES6中的promise

    ES6中的promise对象很早就听说过,据说是为了解决我们使用回调产生回调地狱的问题.今天下午既然有这么想学的欲望,就来看一看吧,当然参考的还是阮一峰老师的教程. 第一部分:什么是Promise 看本文的最后一个例子,迅速理解. Promise是ES6中的一个内置的对象(实际上是一个构造函数,通过这个构造函数我们可以创建一个Promise对象),它是为了解决异步问题的.Promise的英文意思是承诺. Promise的特点如下: •Promise有三种状态:Pending(进行中).Resol

  • 让微信小程序支持ES6中Promise特性的方法详解

    遇到的问题 微信开发者工具更新版本后, 移除了开发者工具对 ES6 中 Promise 特性原生的支持, 理由是因为实体机器是不支持 Promise 的, 所以我们需要引入第三方的 Promise 库 微信更新日志 解决方案 下载第三方库 在这里我引入的是 Bluebird 库, 可以到Bluebird官网 下载需要的文件,也可以通过本地下载 Bluebrid 提供了两种已经构建好的完整的 Promise 库文件, 未经压缩的 bluebird.js 和已压缩的 bluebird.min.js

  • 微信小程序 引入es6 promise

    微信小程序开发两个月了.大家的项目都在不断迭代.已经不是小程序.这时候就会遇到多层回调嵌套的问题.有些目不忍视了.迫不得已引入es6-promise.在微信小程序内测的时候promise不需要手动引入,后来被微信移除了.看看效果. promise详细的介绍我就不说了.有很多大神写过. 看看目录,引入es6-promise就可以用了. 目录 1.网络请求 wxRequest.js 这里只写了get和post. 我经常会在网络请求的时候用微信原生showToast(),所以最后加了finally,方

  • ES6新特性六:promise对象实例详解

    本文实例讲述了ES6新特性之promise对象.分享给大家供大家参考,具体如下: 1. promise 介绍 它是一个对象,也就是说与其他JavaScript对象的用法,没有什么两样:其次,它起到代理作用(proxy),充当异步操作与回调函数之间的中介.它使得异步操作具备同步操作的接口,使得程序具备正常的同步运行的流程,回调函数不必再一层层嵌套. 它的思想是,每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程.这个Promises对象有一个then方法,允许

  • 如何利用ES6进行Promise封装总结

    原生Promise解析 简介 promise是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和强大. promise简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,从语法上来说,Promise是一个对象,从它可以获取异步操作的消息,Promise提供统一的API,各种异步操作都可以用同样的方法进行处理 特点 对象的状态不受外界影响,Promise对象代表一个异步操作,有三种状态:Pendding.fulfilled.rejected.只有异

  • ES6 Promise对象概念与用法分析

    本文实例讲述了ES6 Promise对象概念与用法.分享给大家供大家参考,具体如下: 1.Promise概念 Promise 对象有三种状态: ① Fulfilled 可以理解为成功的状态 ② Rejected 可以理解为失败的状态 ③ Pending 既不是 Fulfilld 也不是 Rejected 的状态,可以理解为 Promise 对象实例创建时候的初始状态 2.三个重要方法 在 Promise 对象当中有三个重要方法----resolve, reject和then. resolve 方

  • ES6中的Promise代码详解

    废话不多说了,直接给大家贴代码了,具体如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script> var a=0 var test=function(resolve, reject){ setTimeou

随机推荐