- Promise的作用
- Promise使用流程
- Promise原理及注意点
- Promise其他用法
本文总结一下自己对于Promise的一点理解
Promise的作用
解决回调地狱;而这又涉及到另一个知识点,即何为回调地狱?
回调地狱
异步回调,层层嵌套;
以下代码就是回调地狱:
//需求:依次读取abcd文件内容 /* 异步代码有序执行 : 异步嵌套 */ const fs = require('fs'); //1.读取文件a fs.readFile(`${__dirname}/data/a.txt`, 'utf8', (err, data) => { if (err) { throw err; } else { console.log(data); //2.读取文件b fs.readFile(`${__dirname}/data/b.txt`, 'utf8', (err, data) => { if (err) { throw err; } else { console.log(data); //3.读取文件c fs.readFile(`${__dirname}/data/c.txt`, 'utf8', (err, data) => { if (err) { throw err; } else { console.log(data); //4.读取文件d fs.readFile(`${__dirname}/data/d.txt`, 'utf8', (err, data) => { if (err) { throw err; } else { console.log(data); } }); } }); } }); } });
Promise使用流程
Promise是一个构造函数,用于创建实例对象
- 创建promise实例对象 : let p = new Promise( (resolve,reject)=>{ //异步操作 });
- 调用实例对象的then方法 : p.then(data=>{},err=>{})
使用Promise解决回调地狱
//需求:依次读取abcd文件内容 /* 异步代码有序执行 : 异步嵌套 */ const fs = require('fs'); //1 创建promise实例对象 : let p = new Promise(); let p1 = new Promise((resolve, reject) => { //异步操作 fs.readFile(`${__dirname}/data/a.txt`, 'utf8', (err, data) => { if (!err) {//成功 /* (1)异步操作成功:调用resolve() (2)调用resolve()本质调用then()方法第一个函数 */ resolve(data); } else { /* (1)异步操作失败:调用reject() (2)reject()本质调用then()方法第二个函数 */ reject(err); } }); }); let p2 = new Promise((resolve, reject) => { //异步操作 fs.readFile(`${__dirname}/data/b.txt`, 'utf8', (err, data) => { if (!err) {//成功 resolve(data); } else { reject(err); } }); }); let p3 = new Promise((resolve, reject) => { //异步操作 fs.readFile(`${__dirname}/data/c.txt`, 'utf8', (err, data) => { if (!err) {//成功 resolve(data); } else { reject(err); } }); }); let p4 = new Promise((resolve, reject) => { //异步操作 fs.readFile(`${__dirname}/data/d.txt`, 'utf8', (err, data) => { if (!err) {//成功 resolve(data); } else { reject(err); } }); }); //2 调用实例对象的then方法 : p.then() //第一个参数: 异步成功需要执行的函数 第二个参数:异步失败需要执行的函数 p1.then(data => { console.log(data); return p2;//在p1的then方法中返回p2 }) .then(data=>{//p2的then console.log(data); return p3; }) .then(data=>{//p3的then console.log(data); return p4; }) .then(data=>{//p4的then console.log(data); });
Promise解决回调地狱函数封装
//需求:依次读取abcd文件内容 /* 异步代码有序执行 : 异步嵌套 */ const fs = require('fs'); function createPromise(filename){ return new Promise((resolve,reject)=>{ fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => { if (!err) {//成功 resolve(data); } else { reject(err); } }); });; } //1 创建promise实例对象 : let p = new Promise(); let p1 = createPromise('a'); let p2 = createPromise('b'); let p3 = createPromise('c'); let p4 = createPromise('d'); //2 调用实例对象的then方法 : p.then() //第一个参数: 异步成功需要执行的函数 第二个参数:异步失败需要执行的函数 p1.then(data => { console.log(data); return p2;//在p1的then方法中返回p2 }) .then(data=>{//p2的then console.log(data); return p3; }) .then(data=>{//p3的then console.log(data); return p4; }) .then(data=>{//p4的then console.log(data); });
Promise原理及注意点
Promise对象有三种状态
- pending(进行中)
- fulfilled(已成功)
- rejected(已失败)
在阮一峰的es6手册中,他将Promise举例成
容器
,我对容器还不太理解;所以,此处我通过将Promise举例成中介
的方式来理解它
Promise的三种状态可以举例成中介办事的三种状态,比如我们需要办理车辆过户
(事物)
,一旦我们交给Promise/中介
之后,只有异步操作/中介办理
的结果,可以决定当前是哪一种状态,且无法更改;
- 正在办理 -> pending(进行中)
- 办理完成 -> fulfilled(已成功)
- 办理失败 -> rejected(已失败)
Promise状态改变只有两种情况
- 从 pending(进行中) -> fulfilled(已成功)
- 从 pending(进行中) -> rejected(已失败)
此处也与中介的办理流程类比,在办理的过程中你向中介致电,也只会得到以上两种情况
- 正在办 -> 办理成功(执行成功回调/交接证件资料等)
- 正在办 -> 办理失败(执行错误回调/告知办理失败的原因)
Promise一旦创建,异步就会立即执行。
Promise一旦创建,异步就会立即执行。对应的,中介一旦收费,就会立即执行.
- 不要在Promise里面去获取异步结果,因为异步本身还是无序的
- 应该通过then方法去获取异步结果
Promise如何控制异步顺序
在上一个promise实例对象的then()方法中返回下一个promise实例对象
一点理解
Promise(容器/中介)本质不是修改异步的顺序(异步永远都是无序的),而是通过控制异步结果的顺序从而间接控制异步的顺序。
Promise其他用法
catch
用于捕捉promise的错误信息
//需求:依次读取abcd文件内容 /* 异步代码有序执行 : 异步嵌套 */ const fs = require('fs'); function createPromise(filename){ return new Promise((resolve,reject)=>{ fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => { if (!err) {//成功 resolve(data); } else { reject(err); } }); });; }; //1 创建promise实例对象 : let p = new Promise(); let p1 = createPromise('a'); let p2 = createPromise('b'); let p3 = createPromise('c'); let p4 = createPromise('d'); //将多个promise放入数组中, 只有数组中所有的promise执行完毕才会执行all的then方法 let pAll = Promise.all([p1,p2,p3,p4]); //2 调用实例对象的then方法 : p.then() //第一个参数: 异步成功需要执行的函数 第二个参数:异步失败需要执行的函数 p1.then(data => { console.log(data); return p2;//在p1的then方法中返回p2 }) .then(data=>{//p2的then console.log(data); return p3; }) .then(data=>{//p3的then console.log(data); return p4; }) .then(data=>{//p4的then console.log(data); }) .catch(err=>{ //上面任何一个then方法出错了,就会执行这个catch方法 console.log(err); });
all
将多个promise放入数组中, 只有数组所有的promise执行完毕才会执行all的then方法
//需求:依次读取abcd文件内容 /* 异步代码有序执行 : 异步嵌套 */ const fs = require('fs'); function createPromise(filename){ return new Promise((resolve,reject)=>{ fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => { if (!err) {//成功 resolve(data); } else { reject(err); } }); });; }; //1 创建promise实例对象 : let p = new Promise(); let p1 = createPromise('a'); let p2 = createPromise('b'); let p3 = createPromise('c'); let p4 = createPromise('d'); //将多个promise放入数组中, 只有数组中所有的promise执行完毕才会执行all的then方法 let pAll = Promise.all([p1,p2,p3,p4]); //2 调用实例对象的then方法 : p.then() //第一个参数: 异步成功需要执行的函数 第二个参数:异步失败需要执行的函数 pAll.then(data=>{ /* 执行时机:数组中所有的promise执行完毕 */ //data: 数组。 存储对应的promise的data数据 console.log(data); }) .catch(err=>{ //上面任何一个then方法出错了,就会执行这个catch方法 console.log(err); })
race
将多个promise放入数组中,只要数组中任意promise执行完毕才会执行race的then方法
//需求:依次读取abcd文件内容 /* 异步代码有序执行 : 异步嵌套 */ const fs = require('fs'); function createPromise(filename){ return new Promise((resolve,reject)=>{ fs.readFile(`${__dirname}/data/${filename}.txt`, 'utf8', (err, data) => { if (!err) {//成功 resolve(data); } else { reject(err); } }); });; }; //1 创建promise实例对象 : let p = new Promise(); let p1 = createPromise('a'); let p2 = createPromise('b'); let p3 = createPromise('c'); let p4 = createPromise('d'); //将多个promise放入数组中,只要数组中任意promise执行完毕才会执行race的then let pAll = Promise.race([p1,p2,p3,p4]); //2 调用实例对象的then方法 : p.then() //第一个参数: 异步成功需要执行的函数 第二个参数:异步失败需要执行的函数 pAll.then(data=>{ /* 执行时机:数组中第一个完成的promise */ //data: 第一个完成的promise console.log(data); }) .catch(err=>{ //上面任何一个then方法出错了,就会执行这个catch方法 console.log(err); })