前端提高篇(132):es6异步promise与异步

创建

创建一个pending状态的promise对象

new Promise()传进的参数是一个函数,会立即执行,可以注入两个参数,代表成功或失败的回调函数,setTimeout用来模拟请求的发送

// 创建一个pending状态的promise对象 const p = new Promise((resolved, rejected)=>{     setTimeout(function(){         // resolved(1000); // 异步操作成功时调用         rejected(new Error("出错了")); // 异步操作失败时调用     },1000) }) console.log( p ); p.then(function(value){     console.log(value); }, // 成功回调 function(err){     console.log(err); // 失败回调 })  
前端提高篇(132):es6异步promise与异步

创建一个已处理的promise对象(已成功)

// 创建一个已处理的promise对象 const p1 = Promise.resolve(); console.log( p1 ); 
前端提高篇(132):es6异步promise与异步

创建一个已处理的promise对象(已失败)

// 创建一个已处理的promise对象(已失败) const p2 = Promise.reject(); console.log( p2 ) 
前端提高篇(132):es6异步promise与异步

使用

状态

仅有pending转resolved、pending转rejected两种可能

promise链式调用,解决回调金字塔问题

如果下一次请求需要前一次的数据,就需要在前一次调用的回调代码里写上这一次调用的代码,类似这样:
前端提高篇(132):es6异步promise与异步
这样一层层嵌套下去,代码就显得很复杂,不好维护
then()返回的是一个promise对象,可以使用链式调用

规则:
then()的请求成功或失败,看的是return的是否为promise对象:
如果返回的是promise对象,则请求失败,执行失败的回调函数;
如果返回的不是promise对象,代表请求成功,执行成功的回调函数

举例:
返回的不是promise对象,即请求均成功:

const p = new Promise((resolved, rejected)=>{     setTimeout(function(){         resolved(1000); // 异步操作成功时调用     },1000) }) // p.then返回的promise对象已不是原来的p p.then(function(value){ // 记作f1     console.log(value); // 输出1000     return 111; }, function(err){ // 记作f2     console.log(err); }) .then(function(value){ // 记作f3     console.log(value); // 输出111 }, function(22){  // 记作f4     console.log(22); }) 

异步操作p成功,执行f1,f1返回的不是一个promise对象,代表请求又成功了,就会调用f3,总体输出的是:1000 111
如果p失败,执行f2,由于没有return,默认代表是return undefined,则第一个p.then请求成功,执行f3;f2没有return,f3没有接收到value,所以输出的是undefined

返回的是promise对象:
p成功,且第一个p.then在1s之后成功:

const p = new Promise((resolved, rejected) => {     setTimeout(function () {         resolved(1000); // 异步操作成功时调用     }, 1000) }) p.then(function (value) { // p成功后调用此处     console.log(value); // 输出1000     return new Promise((resolved, rejected)=>{         setTimeout(function () {             resolved(11);         }, 1000)})     }, // p.then成功     function (err) {         console.log(err);     })     .then(function (value) { // 第一个p.then成功后调用此处         console.log(value); // 输出11     },     function () {         console.log(22);     }) 

p成功,但第一个p.then在1s之后失败:

const p = new Promise((resolved, rejected) => {     setTimeout(function () {         resolved(1000); // 异步操作成功时调用     }, 1000) }) p.then(function (value) { // p成功后调用此处     console.log(value); // 1000     return new Promise((resolved, rejected)=>{         setTimeout(function () {             rejected(); // 此处rejected,代表整个p.then失败         }, 1000)})     },     function (err) {         console.log(err);     })     .then(function (value) {         console.log(value);     },     function () { //上一个p.then失败,调用此处         console.log(22); // 22     }) 

用链式调用代替回调金字塔

// 用链式调用解决回调金字塔 // 10s后打印10,再20s后打印20,再30s后打印30,打印的数字和等待的时间均由前一次请求指定 function fakeAjax(time, val) {     return new Promise((resolved, rejected) => {         setTimeout(function () {             resolved(val);         }, time)     }) }  fakeAjax(1000, 10).then((val) => {     console.log(val);     return fakeAjax(2000, 20); },     () => { } )     .then((val) => {         console.log(val);         return fakeAjax(3000, 30)     },     () => {})     .then((val) => {         console.log(val);     }) 

响应多个promise对象

1.Promise.all :所有请求都成功时成功,其中一个失败,则整体失败
2.Promise.race:看响应最快的那个请求,如果成功,就执行成功的回调函数,失败,则整个失败,不再往后判断执行

Promise.all VS 完全成功:

function fakeAjax(time, val) {     return new Promise((resolved, rejected) => {         setTimeout(function () {             resolved(val);         }, time)     }) } var p1 = fakeAjax(1000,10); var p2 = fakeAjax(2000,20); var p3 = fakeAjax(1500,30); Promise.all([p1,p2,p3])     .then(function(val){         console.log(val); // 2s后输出[10, 20, 30]     },     function(err){         console.log(err);     }) 

Promise.all VS 其中一个不成功:

function fakeAjax(time, val, flag) {     return new Promise((resolved, rejected) => {         setTimeout(function () {             if (flag){                 resolved(val);             }             else {                 rejected(new Error("出错"))             }                      }, time)     }) } // flag为true时,成功 var p1 = fakeAjax(1000,10,true); var p2 = fakeAjax(2000,20,true); var p3 = fakeAjax(1500,30,false); Promise.all([p1,p2,p3])     .then(function(val){         console.log(val);     },     function(err){         console.log(err); //打印错误信息     }) 

Promise.race VS 最快的请求是成功的

var p1 = fakeAjax(1000,10,true); var p2 = fakeAjax(2000,20,true); var p3 = fakeAjax(1500,30,false); Promise.race([p1,p2,p3])     .then(function(val){         console.log(val); // 打印10     },     function(err){         console.log(err);     }) 

Promise.race VS 最快的请求是失败的:

var p1 = fakeAjax(1000,10,false); var p2 = fakeAjax(2000,20,true); var p3 = fakeAjax(1500,30,false); Promise.race([p1,p2,p3])     .then(function(val){         console.log(val);     },     function(err){         console.log(err); //打印错误信息     }) 

catch()也代表失败回调函数,相当于then(null, ()=>{})

版权声明:玥玥 发表于 2021-04-28 2:52:50。
转载请注明:前端提高篇(132):es6异步promise与异步 | 女黑客导航