Axios -- 简单易懂Promise

目录

了解Promise

Promiseの链式操作及Resolve的用法

Reject的用法

Catch的用法

all的用法

Race的用法

补充


了解Promise

Promise :ES6提供的一个构造函数,处理异步事件。接收了一个参数为函数,传入resolve,reject两个参数。resolve为异步操作成功后执行的回调函数,reject为异步操作失败后执行的回调函数。Promise对象上有then,catch方法。例子:

function snycA(){
    const promise = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('执行完成');
            resolve('异步数据1');
        },2000)        

    })
    return promise
}

snycA().then((response)=>{
    console.log(response);
    
})

输出的结果为:

                      

Emmmmm...然而这种操作不就跟平时我们使用回调函数(将回调函数作为参数传入函数里,函数里面嵌套函数,等函数执行完成再去执行嵌套函数,就叫回调函数啦)一样了吗?下面的例子就是用回调函数实现上面所实现的效果:

//将callback作为一个参数传入函数中,待函数执行完成再执行回调函数
function syncA(callback){
    setTimeout(()=>{
        console.log("执行完成");
        callback('回调数据1');
    },2000)
}

syncA((data)=>{
    console.log(data)
})

输出的结果为: 

                

虽然回调函数也能实现同样的效果,但是,如果callback也是一个异步操作,而且执行完后也需要有相应的回调函数,该怎么办呢?总不能再定义一个callback2,然后给callback传进去吧。而Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。  

Promiseの链式操作及Resolve的用法

promise能层层简化多层回调的写法,而Promise的精髓在于维护状态,传递状态。下面来简单实现一下

function syncA(){
   const P = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('执行syncA');
            resolve('syncA-over')
        })
        
   })
   return P;
}
function syncB(){
   const P = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('执行syncB');
            resolve('syncB-over')
        })
        
   })
   return P;
}
function syncC(){
   const P = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('执行syncC');
            resolve('syncC-over')
        })
        
   })
   return P;
}
syncA().then((data)=>{
    console.log(data);
    return syncB();
}).then((data)=>{
    console.log(data);
    return syncC();
}).then((data)=>{
    console.log(data)
})

输出结果为:

这样,每隔两秒输入按顺序输出syncA,syncB,syncC中的内容并执行,传入resolve()的数据在then中也能直接拿到。

Reject的用法

reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。看下面的代码。

//随机生成一个1-10的数字,当数字小于8时调用reject,在then在输出
function syncA(){
    const P = new Promise((reslove,reject)=>{
        setTimeout(()=>{
            let num = Math.floor((Math.random * 10)+1)
            if(num>8){
                reslove(num)
            }else{
                reject('小于8')
            }

        })
       
    })
    return P;
}

syncA().then((num)=>{
    console.log(num)
},(data)=>{
    console.log(data)
})

输出结果为:

                     

Catch的用法

catch方法与then中的第二个参数一样,用来指定reject的回调,也就是上面的代码可以写成:

syncA().then((num)=>{
    console.log(num)
})
.catch((data)=>{
    console.log(data)
})

catch还有一个重要的作用!!!!当then方法中resolve抛出异常(代码错误)时,也会进入到我们的catch中,将错误信息传入到我们的catch中,代码继续往下执行,并不会中断!与我们的try/catch语句有相同的功能。

all的用法

用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。   有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,是不是很酷?有一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。  

function syncA(){
   const P = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('执行syncA');
            resolve('syncA-over')
        })
        
   })
   return P;
}
function syncB(){
   const P = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('执行syncB');
            resolve('syncB-over')
        })
        
   })
   return P;
}
function syncC(){
   const P = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('执行syncC');
            resolve('syncC-over')
        })
        
   })
   return P;
}
Promise
.all([syncA(), syncB(), syncC()])
.then(function(results){
    console.log(results);
})

输出的结果为:

                       

Race的用法

race是 【谁跑的快,以谁为准执行回调函数】

//请求某个图片资源
function requestImg(){
    var p = new Promise(function(resolve, reject){
        var img = new Image();
        img.onload = function(){
            resolve(img);
        }
        img.src = 'xxxxxx.jpg';
    });
    return p;
}
 
//延时函数,用于给请求计时
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('图片请求超时');
        }, 5000);
    });
    return p;
}

Promise.race([requestImg(),timeout()])
       .then((results)=>{
            console.log(results)
        })
       .catch((reason)=>{
            console.log(reason)
        })

requestImg函数会异步请求一张图片,我把地址写为"xxxxxx",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。

 

补充

8.19:resolve是不接受多个参数的,如resolve(a,b)的时候,b将会被忽略。应改为resolve([a,b])&&sync().then([a,b]),下面是微信群里分享的网易云一面题目以及我的答案

function getValue (a, b) {
  const P = new Promise((resolve) => {
    setTimeout(() => {
      resolve([a, b])
    }, 2000)
  })
  return P
}
getValue(1, 2).then(([a, b]) => {
  return a + b
})

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值