前端开发那些事儿

Promise async/await

2020-11-01  本文已影响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会阻塞后面的代码,等主程序执行完,再回来执行

上一篇下一篇

猜你喜欢

热点阅读