js异步转为同步 用await async promise

var gameArr = {
    codeOne:[
        {
            code: "code1",
        },
    ],
    codeTwo:[
        {
            code: "code2",
        },
    ],
}
Object.keys(gameArr).forEach(function(j,k){
    for(var i = 0; i < gameArr[j].length; i++){
        accountApi({
            code: gameArr[j][i].code
        }).then(res => {
            console.log(gameArr[j][i])
        }).catch(err => {

        })
    }
})
// 打印输出:undefined

我们都知道JS是单线程的,js的代码只能在一个线程上运行,上面代码接口交上开新的线程,所以拿不到主线程。

在项目中有些逻辑或者请求依赖另一个异步请求,我深入查阅相关资料,看到比较高大上的解决方案就是:await async。

async 是“异步”的简写,而 await 可以认为是 async wait 的简写。所以应该很好理解 async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。并且await 只能出现在 async 函数中,否则会报错。

async作用:

当调用一个 async 函数时,会返回一个Promise对象。当这个 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。

async 函数中可能会有 await 达式,这会使 async 函数暂停执行,等待 Promise的结果出来,然后恢复async函数的执行并返回解析值(resolved)。

await作用:

await 表达式会暂停当前async function的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行async function

若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。

function getData(data) {
    return accountApi({code:data})
}
async function asyncCall() {
    Object.keys(gameArr).forEach(function(j,k){
        for(var i = 0; i < gameArr[j].length; i++){
            await getData(gameArr[j][i].gameCode)
        }
    })
}
asyncCall()

js异步转为同步 用await async promise_第1张图片

 在forEach中使用async报错,应该是forEach不知道await它迭代的异步函数

改成下面:

function getData(data) {
    return accountApi({code:data})
}
async function asyncCall() {
    for (let j of Object.keys(gameArr)){
        for(var i = 0; i < gameArr[j].length; i++){
            await getData(gameArr[j][i].gameCode)
        }
    }
}
asyncCall()

等等,我仔细地发现请求一个接口返回成功或错误才请求下一个接口,发起几个请求,请求中有一定的时间,会费很多时间,用户体验不好。

我加这个红圈并打印输出,能看出来执行完一个后才执行下一个

js异步转为同步 用await async promise_第2张图片

function getData(data) {
    console.log(new Date())
    return new Promise(resolve => {
        accountApi({code:data})
        setTimeout(() => {
            resolve('resolved2');
        }, 2000);
    });
}
async function asyncCall() {
    for (let j of Object.keys(gameArr)){
        for(var i = 0; i < gameArr[j].length; i++){
            var data = await getData(gameArr[j][i].gameCode)
        }
    }
    console.log(data)
}
asyncCall()

// 打印输出:
// Fri Nov 12 2021 23:05:31 GMT+0800 (中国标准时间)
// Fri Nov 12 2021 23:05:33 GMT+0800 (中国标准时间)
// resolved2

需要改成一次性执行所有,如下:

function getData(data) {
    console.log(new Date())
    return new Promise(resolve => {
        accountApi({code:data})
        setTimeout(() => {
            resolve('resolved2');
        }, 2000);
    });
}
async function asyncCall() {
    for (let j of Object.keys(gameArr)){
        for(var i = 0; i < gameArr[j].length; i++){
            var data = getData(gameArr[j][i].gameCode)
        }
    }
    var data1 = await data
    console.log(data1)
}
asyncCall()

// 打印输出:
// Fri Nov 12 2021 23:18:35 GMT+0800 (中国标准时间)
// Fri Nov 12 2021 23:18:35 GMT+0800 (中国标准时间)
// resolved2

所有接口同时发送的优化思路,最终代码:

function getData(data) {
    return accountApi({code:data})
}
async function asyncCall() {
    for (let j of Object.keys(gameArr)){
        for(var i = 0; i < gameArr[j].length; i++){
            var data = getData(gameArr[j][i].gameCode)
        }
    }
    await data
}
asyncCall()

你可能感兴趣的:(javascript,es6,前端)