Promise async/await

作者: 肖青荣 | 来源:发表于2020-11-01 11:31 被阅读0次

    promise是异步编程的一种解决方案,那么为什么要使用promise呢?
    比如说,当我们封装一个网络请求,因为不能立即拿到结果,所以不能像简单的函数一样将结果返回,所以我们会传入另一个函数,在请求成功时将数据通过该函数回调出去。
    但是,当请求比较复杂时,就会出现回调地狱。

     $.ajax(url, function (data1) {
         $.ajax(data1['url2'], function(data2) {
           $.ajax(data2['url3'], function(data3) {
              console.log(data3)
           })
         })
       })
    

    可以看到,我们需要通过一个url从服务器加载一个data1,data1中包含了下一个请求的url2,
    这时就需要从data1中取出url2,在加载url2,再去请求url3。
    这样的话,代码较难看,而且逻辑乱且不易维护
    那么promise能更好的解决这个问题,下面我们用定时器模仿网络请求。

      setTimeout(() => {
            console.log('hello world')
            setTimeout(() => {
                console.log('hello javascript')
                setTimeout(() => {
                    console.log('hello vue')
                },1000)
            },1000)
         },1000)
    
    通过promise
    new Promise((resolve,reject) => {
           //第一次网络请求
            setTimeout(() => {
                resolve()
            },1000)
          }).then(() => {
            console.log('hello world')
    
            return new Promise((resolve,reject) => {
             //第二次网络请求
              setTimeout(() => {
                resolve()
              },1000)
            }).then(() => {
                console.log('hello javascript')
    
             return new Promise((resolve,reject) => {
              //第三次网络请求
              setTimeout(() => {
                resolve()
              },1000)
            }).then(() => {
                console.log('hello vue')
            })
          })
    

    只要有异步操作,我们就返回一个promise对象,这样代码虽然更多了,但逻辑更清晰了,也更好维护

    promise的三种状态

    pending:等待状态, 比如正在进行网络请求,或者定时器没到时间
    fulfilled: 成功状态,当我们主动回调resolve时,就处于该状态,并且回调.then()
    rejected:拒绝状态,当我们主动回调reject时,就处于该状态,并且回调.catch()

    promise.all

    promise.all可以将多个promise实例包装成一个新的promise实例。同时,成功和失败的返回值是不同的,
    成功的时候返回一个数组,失败时则返回最先被reject失败的状态的值。
    所有的请求都完成时,才返回一个数组
    只要有一个失败了,就先返回这个失败的请求

            let p1 = new Promise((resolve,reject) => {
                resolve('成功了')
            })
    
            let p2 = new Promise((resolve,reject) => {
                resolve('success')
            })
    
            let p3 = new Promise((resolve,reject) => {
                reject('失败了')
            }) 
    
            Promise.all([p1, p2]).then(res => {
                console.log(res)  //[ '成功了', 'success' ]
            }).catch(err => {
                console.log(err)
            })
    
            Promise.all([p1, p2, p3]).then(res => {
                console.log(res)  
            }).catch(err => {
                console.log(err) // 失败了
            })
    
    promise.race

    顾名思义,promise.race就是赛跑的意思,就是说promise.race([p1, p2, p3])里哪个结果捕获的快,就返回哪个结果
    不管成功还是失败

      let p1 = new Promise((resolve,reject) => {
                setTimeout(() => {
                    resolve('成功了')
                },1000)
            })
    
            let p2 = new Promise((resolve,reject) => {
                setTimeout(() => {
                    reject('失败了')
                },500)  
            }) 
    
            Promise.race([p1, p2]).then(res => {
                console.log(res)  
            }).catch(err => {
                console.log(err)
            })
    
    async/await

    async/await是es7出的一种解决异步的一种方案, 背后原理就是promise,当一个函数前面加上async,那么他就成了一个异步函数

    async
    async function f1() {
                return "abc"
            }
            console.log(f1())
    

    上面的代码其实等同于

    return new Promise(resolve => {
                resolve('abc')
            })
    
    与await结合
     async function f3() {
                return 'f3';
            }
    
            async function f4() {
                return 'f4';
            }
    
            async function f5() {
                var a = await f4();
                var b = await f5();
                console.log(a, b)
            }
           f5()
    

    await会阻塞后面的代码,等主程序执行完,再回来执行

    相关文章

      网友评论

        本文标题:Promise async/await

        本文链接:https://www.haomeiwen.com/subject/daffvktx.html