17

ES6中的Promise使用总结

 4 years ago
source link: http://www.cnblogs.com/btsn/p/12500341.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

One、什么是Promise?

Promise是异步编程的解决方案,而它本身也就是一个构造函数,比传统的异步解决【回调函数】和【事件】更合理,更强大。

Two、Promise有何作用?

作用:解决回调地狱

当我们在写逻辑函数时,可能函数内部会有另一个函数,而我们在处理一些比较复杂的操作的时候,有可能里面会嵌套十几二十个函数都说不定,那么看一下下面的代码:


 1 //需求 : 异步操作按照顺序执行(异步默认无序)
 2 
 3 //需求: (1)先读取a  (2)然后读取b (3)然后读c  (4)最后读取d
 4 
 5 
 6 const fs = require('fs');
 7 
 8 //下面出现了回调地狱
 9 //(1)读取A
10 fs.readFile('./data/a.txt', 'utf8', (err, data) => {
11     if (err) {
12         throw err;
13     } else {
14         console.log(data);
15         //(2)读取B
16         fs.readFile('./data/b.txt', 'utf8', (err, data) => {
17             if (err) {
18                 throw err;
19             } else {
20                 console.log(data);
21                 //(3)读取C
22                 fs.readFile('./data/c.txt', 'utf8', (err, data) => {
23                     if (err) {
24                         throw err;
25                     } else {
26                         console.log(data);
27                         //(4)读取D
28                         fs.readFile('./data/d.txt', 'utf8', (err, data) => {
29                             if (err) {
30                                 throw err;
31                             } else {
32                                 console.log(data);
33                             }
34                         })
35                     }
36                 })
37             }
38         })
39     }
40 })

View Code

像这样的代码维护起来非常麻烦,那么如何使用Promise来解决?看下来:

Three、promise基本使用:

(1)实例化promise对象(将异步放入promise容器)

let p = new Promise((resolve,reject)=>{ 你的异步操作 })

(2)调用promise实例的then方法 (处理异步结果) : 

p.then(data=>{},err=>{})

再看一个根据上面优化的代码:


 1 const fs = require('fs');
 2 
 3 //1.创建Promise实例化对象  (Promise是一个构造函数,作用是创建promise实例)
 4 //参数是一个回调函数 :  (resolve, reject)=>{ 你的异步操作 }
 5 let p = new Promise((resolve,reject)=>{
 6     fs.readFile('./data/b.txt','utf8',(err,data)=>{
 7         if(!err){
 8             //成功
 9             /* 
10             1.成功就执行resolve() , 会调用then的第一个函数
11             */
12             resolve(data);
13         }else{
14             //失败
15             /* 
16             2.失败就执行reject(),会调用then的第二个函数
17             */
18             reject(err);
19         }
20     });
21 });
22 
23 
24 //2.调用promise实例的then方法
25 /* 
26 第一个参数:  回调函数  (data)=>{}
27 第二个参数:  回调函数  (err)=>{}
28 */
29 p.then(data=>{
30     //成功
31     console.log(data);
32     
33 },err=>{
34     //失败
35     console.log(err);
36     
37 });

View Code

Four、Promise原理介绍 :

(1)promise有三种状态

pending:进行中

fulfilled:已成功

rejected:已失败

1----- 只有异步操作的结果,可以决定Promise是哪一种状态,任何其他操作都无法改变这个状态

2----- 一旦Promise状态改变,就不会再有变化,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled 或者 从pending变为rejected。只要这两种情况发生,状态就不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的

使用Promise的好处,就是在处理异步程序时,将异步操作队列化,按照期望的顺序执行,返回符合预期的结果,这样即使是多重异步操作,也可以方便的使用Promise进行链式调用

3----- Promise 也有一些缺点

首先,无法取消 Promise ,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数, Promise 内部抛出的错误,不会反应到外部。第三,当处于 pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

第二部分、循序渐进的介绍Promise的用法

(2)promise状态改变只有两种情况

从pending进行中变成fulfilled:已成功

从pending进行中变成rejected: 已失败

(3)promise中的异步函数在创建的时候会默认执行

* a. 异步永远都是无序的,这一点无法改变的

* b. promise没有改变异步的顺序,而是改变异步的结果

* c. 不要在创建promise的时候去操作异步的结果,应该调用resolve在then方法种操作结果

(4)promise控制异步操作顺序的核心原理 : 在上一个promise的then方法中return下一个promise


 1 const fs = require('fs');
 2 
 3 //需求: (1)先读取a  (2)然后读取b (3)然后读c  (4)最后读取d
 4 
 5 //(1)实例化promise对象
 6 let p1 = new Promise((resolve,reject)=>{
 7     //异步操作
 8     fs.readFile('./data/a.txt','utf8',(err,data)=>{
 9         if(!err){//成功执行的操作
10             /* 
11             (1)resolve() 调用then的第一个函数
12             (2)作用: 改变promise的状态 从 从pending进行中变成fulfilled:已成功
13             */
14             resolve(data);
15             
16         }else{
17             /* 
18             (1)resolve() 调用then的第二个函数
19             (2)作用: 从pending进行中变成rejected: 已失败
20             */
21             reject(err);
22         };
23     });
24 });
25 
26 let p2 = new Promise((resolve,reject)=>{
27     //异步操作
28     fs.readFile('./data/b.txt','utf8',(err,data)=>{
29         if(!err){//成功执行的操作
30             resolve(data);
31         }else{
32             reject(err);
33         };
34     });
35 });
36 
37 let p3 = new Promise((resolve,reject)=>{
38     //异步操作
39     fs.readFile('./data/c.txt','utf8',(err,data)=>{
40         if(!err){//成功执行的操作
41             resolve(data);
42         }else{
43             reject(err);
44         };
45     });
46 });
47 
48 //(2)调用promise实例的then方法
49 
50 p1.then(data=>{
51     console.log(data);   //这是p1的数据
52     return p2;//在p1的then方法中返回p2
53 })
54 .then(data=>{//调用p2的then方法
55     console.log(data);   //这是p2的数据
56     return p3;
57 })
58 .then(data=>{//调用p3的then方法
59     console.log(data);   //这是p3的数据
60 });

View Code

精辟个人总结:promise控制异步顺序的本质  不是控制异步操作的本身 ,而是控制异步操作的结果

Five、Promise的catch方法的使用:

catch作用: 捕捉promise的异常


 1 const fs = require('fs');
 2 
 3 //需求: (1)先读取a  (2)然后读取b (3)然后读c  (4)最后读取d
 4 
 5 function getPromise(fileName) {
 6     return new Promise((resolve, reject) => {
 7         //异步操作
 8         fs.readFile(`./data/${fileName}.txt`, 'utf8', (err, data) => {
 9             if (!err) {//成功
10                 resolve(data);
11             } else {
12                 reject(err);
13             };
14         });
15     });
16 }
17 
18 /* catch作用: 捕捉promise的异常 */
19 
20 //(1)实例化promise对象
21 let p1 = getPromise('a');
22 let p2 = getPromise('b');
23 let p3 = getPromise('c');
24 
25 //(2)调用promise实例的then方法
26 p1.then(data=>{
27     console.log(data);
28     return p2;
29 }).then(data=>{
30     console.log(data);
31     return p3;
32 }).then(data=>{
33     console.log(data);
34 }).catch(err=>{
35     //上面所有的promise只要有任何一个出现错误,就会执行catch
36     console.log(err);
37 })

View Code

Six、Promise的all方法的使用:

all作用 :  将多个promise合并成一个promise,所有的promise执行完毕才会走then方法 (&&)


 1 const fs = require('fs');
 2 
 3 //需求: (1)先读取a  (2)然后读取b (3)然后读c  (4)最后读取d
 4 
 5 function getPromise(fileName) {
 6     return new Promise((resolve, reject) => {
 7         //异步操作
 8         fs.readFile(`./data/${fileName}.txt`, 'utf8', (err, data) => {
 9             if (!err) {//成功
10                 resolve(data);
11             } else {
12                 reject(err);
13             };
14         });
15     });
16 }
17 
18 /* 1.catch作用: 捕捉promise的异常
19    2.all作用 :  将多个promise合并成一个promise,所有的promise执行完毕才会走then方法
20 */
21 
22 //(1)实例化promise对象
23 let p1 = getPromise('a');
24 let p2 = getPromise('b');
25 let p3 = getPromise('c');
26 
27 //多个promise合并成一个promise
28 let pAll = Promise.all([p1,p2,p3]);
29 
30 //(2)调用promise实例的then方法
31 pAll.then(data=>{
32     //所有的promise都执行完毕,data是一个数组,存储每一个promise的操作结果
33     console.log(data);
34     return p2;
35 }).catch(err=>{
36     //上面所有的promise只要有任何一个出现错误,就会执行catch
37     console.log(err);
38 })

View Code

Seven、Promise的race方法的使用:

race作用:  将多个promise合并成一个promise,任意primise执行完毕就会走then方法  (||)


 1 //(1)实例化promise对象
 2 let p1 = getPromise('/ada/dada');
 3 let p2 = getPromise('b');
 4 let p3 = getPromise('c');
 5 
 6 //多个promise合并成一个promise
 7 let pAll = Promise.race([p1, p2, p3]);
 8 
 9 //(2)调用promise实例的then方法
10 Promise.race([p1, p2, p3]).then(data => {
11     //任意promise执行完毕就会走then,此时其他的promise不再执行
12     console.log(data);
13 }, (err) => {
14     console.log('有文件错误');
15 })

View Code

喜欢分享,喜欢学习,这些确实是在遇到的问题中解决问题的个人总结,如果喜欢,请点个赞,也欢迎到下方评论,我们一起探讨技术......


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK