async学习记录

136 阅读3分钟

在项目中,我们经常会遇到这样的需求:第二个接口请求的参数必须要等到第一个接口返回值回来,才能去请求第二个接口。也就是说:第二个函数的参数是第一个函数的返回值!

通常遇到这种情况,我们都会想到使用Promise去处理这样的异步需求。因为之前知道除Promise外还有async/await,但是一直没有研究过,今天就来研究一下!

async基础知识参考链接:juejin.cn/post/684490…

一篇关于promise以及async对比的比较通俗简洁的文章:juejin.cn/post/684490…

解决async地狱:juejin.cn/post/684490…

1. 关于async/await的重要点汇总:

  1. 首先,async 永远会返回一个promise函数!
  2. async函数返回的promise,必须等到内部所有的 await命令后面的promise都执行完,整个async函数才能发生状态变化!
  3. async return出来的值会出现在 async的.then回调里面;async 抛出的异常,会被async 的catch回调接收到。
  4. 正常的 async 内部的 await后面都是跟着promise的,如果不是的话,会被转化成一个 立即resolve的promise!
  5. async 内部只要有一个await出现reject状态,后面的await都不会执行! ---> 为所有的await添加try/catch

2. 下面通过直接的代码看看关于异步处理的这点事:

function fetchData(age) {
    return new Promise((resolve, reject) => {
        if (age < 30) {
            const obj = {
                code: 1,
                age: age,
                description: '恭喜!你的年级符合要求!'
            } 
            resolve(obj);
        } else {
            const obj = {
                code: -1,
                age: age,
                description: '抱歉,你的年纪不符合要求!'
            } 
            reject(obj);
        }
    })
}

function calcuteAge(resAge) {
    return new Promise((resolve, reject) => {
        if (resAge.code === 1) {
            resolve('根据你的年级符合要求,请你接下去准备面试')
        } else {
            reject('抱歉,你没有后续了!')
        }
    })
}

3. 我们先来看看Promise的多次then回调是怎么处理异步操作的:

fetchData(18).then(res => {
    if (res.code === 1) {
        calcuteAge(res).then(res => {
            console.log(res);
        })
    }
})

4. 再来看看async/await如何处理异步操作的:

async function filterPerson() {
    let ageCondition = await fetchData(18);
    let mettingOK = await calcuteAge(ageCondition);
    return mettingOK;
}

filterPerson().then(res => {
    console.log(res);
})

5. async/await在内部await返回的不是promise,比如:抛出错误,纯纯的字符串... ,async又会怎么处理那?

async function error() {
    throw new Error('我是抛出的错误');
}

error().then(res => {
    console.log(res);
}).catch(err => {
    console.log(err);  // catch拦截错误提示
})
async function noPromise() {
    return 'hahahah' 
}

noPromise().then(res => {
    console.log(res);  // hahahah
})

6.解决sync地狱

试想这个案例:我们从选择披萨到购物车,然后付钱 并且选择可乐到购物车,生成订单付钱。。。这中间既有异步操作,也可以披萨可乐同步进行!

更好的处理逻辑是:将从【获取披萨列表+选择披萨+添加披萨到购物车+生成订单付钱】这个流程封装成一个关于披萨的异步函数,类似的还有关于可乐购物的整个流程的异步函数。

将selectPizza()及可乐selectDrink()的异步函数,通过Promise.all(),同步一起处理披萨和可乐即可!