Es6新特性之Promise

2022-09-08 15:13:40 浏览数 (1)

什么是Promise 简单来说就是用来统一,封装异步操作的,可以使你以同步的方式去做异步的事情,简化了异步操作的不断的回调

既然Promise是统一异步操作的那么首先我们得知道什么是异步 异步通俗来讲就是,你做你的,我做我的我们之间互不影响,如js中的Ajax

我们先来看以前的异步操作的缺陷,以jq的ajax为例 下面示例发送了3次ajax请求,因为我的请求是有顺序的,我们等第一个ajax请求成功后在执行第二个请求,以此类推。

代码语言:javascript复制
$(function(){
        $.ajax({
            url:'1.json',
            datatype:'json',
            success:function(one){
                $.ajax({
                    url:'2.json',
                    datatype:'json',
                    success:function(two){
                        $.ajax({
                            url:'3.json',
                            datatype:'json',
                            success:function(three){
                                console.log(one,two,three)
                            }
                        })
                    }
                })
            }
        })
    })

就上面的代码看上去已经很乱了,如果请求很多咋办?难得要一直嵌套在success里面?这样也显得太麻烦了,而且不易维护。es6中的promise就是为了解决这个问题应运而生

上面说到Promise是用来统一封装异步操作的 他的基本用法是这样

代码语言:javascript复制
p = new Promise(function(resolve,reject)){
       //异步操作...
       resolve();//成功回调
       reject();//失败回调
}
p.then(function(){'resolve'},function(){'reject'})
//then方法用于异步操作返回数据后调用,成功执行resolve失败失效reject
//失败回调
p.catch((err)=>{

)
//成功失败都执行
p.finally(()=>{

})

**直接使用resolve与reject**

Promise.resolve(5).then(v=>console.log(value))

JQ的ajax是支持promise所以我们跳过他的基本用法,promise最主要的是他的高级用法 这里通过promise.all([])解决上面无限回调的问题

代码语言:javascript复制
Promise.all([
        //等待所有异步操作完成后统一返回then
        $.ajax({url:'1.json',datatype:'json'}),
        $.ajax({url:'2.json',datatype:'json'}),
        $.ajax({url:'3.json',datatype:'json'}),
    ]).then(function(arr){
        console.log(arr)
    },function(err){
        console.log(err)
    })

Promise.race 只要有一个返回结果就立即执行

代码语言:javascript复制
var p1 = Promise.resolve('1')
var p2 = Promise.resolve('2')

let arr = [p1,p2]
var result = Promise.race(arr)
result.then(function(res){
    console.log(res)
})

then的第一个参数就是resolve他会等all里面的所有异步执行完毕后执行,中途有一个请求失败则返回then的第二参数reject,通过这样的操作我们就完成了同步的语法执行异步的事情 不用一直无限回调。

这种方式看似解决了问题,但是如果我后面的ajax需要前面的ajax数据怎么办?没有了回调操作就无法在异步的过程中使用前面ajax的数据,因为他会等待所有异步操作全部执行完毕返回then

这里我们就要引入一个新的东西 es7的async/await async和await配合promise实现真正的以同步的语法去做异步的事情 基本语法 在fn函数通过async关键字说明fn可以进行异步操作,函数体通过await 来指定某个Promise完成后才执行下面的代码

代码语言:javascript复制
async function fn(){
   //函数体可写异步操作
   let a = await Promise对象
   let a = await Promise对象
   let a = await Promise对象
}

到这里我们就可以通过async和await解决上面的问题

代码语言:javascript复制
async function show(){
    let data1 =await $.ajax({url:'1.json',datatype:'json'});
    if(data1.name=='a'){
        console.log('执行a')
        let data2 =await $.ajax({url:'2.json',datatype:'json'});
    }else{
        console.log('执行b')
        let data3 =await $.ajax({url:'3.json',datatype:'json'})
    }
    
} 
show();//执行a

这种方式就可以实现同步语法执行异步,并且后面的ajax可以应用前面ajax的数据,而不用像以前无限的回调。

实际上他的底层还是各种的回调,就像这样

代码语言:javascript复制
let data1 = $.ajax({
    url:'1.json',
    datatype:'json',
    success:function(){
        if(data1.name=='a'){
            console.log('执行a')
            let data2 =await $.ajax({url:'2.json',datatype:'json'});
        }else{
            console.log('执行b')
            let data3 =await $.ajax({url:'3.json',datatype:'json'})
        }
});

0 人点赞