内容简介:One、什么是Promise?Promise是异步编程的解决方案,而它本身也就是一个构造函数,比传统的异步解决【回调函数】和【事件】更合理,更强大。Two、Promise有何作用?
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
喜欢分享,喜欢学习,这些确实是在遇到的问题中解决问题的个人总结,如果喜欢,请点个赞,也欢迎到下方评论,我们一起探讨技术......
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。