前端提高篇(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与异步_第1张图片

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

// 创建一个已处理的promise对象
const p1 = Promise.resolve();
console.log( p1 );

在这里插入图片描述

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

// 创建一个已处理的promise对象(已失败)
const p2 = Promise.reject();
console.log( p2 )

在这里插入图片描述

使用

状态

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

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

如果下一次请求需要前一次的数据,就需要在前一次调用的回调代码里写上这一次调用的代码,类似这样:
前端提高篇(132):es6异步promise与异步_第2张图片
这样一层层嵌套下去,代码就显得很复杂,不好维护
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, ()=>{})

你可能感兴趣的:(前端提高,js,javascript,es6,promise)