js之async, await实用技巧

本文不是科普文章,旨在给出一些关于js中async, await的实用片段,方便工作中提高效率。

同步变异步

看到这有人就奇怪了,好好的同步代码为啥要变异步?
其实我也不想,这有可能是为了后续的扩展。
比如如下场景:有个判断用户登录的方法isLogin, 我们可以在首次进入页面时将登录信息存储起来, 比如使用localStorage, 这样就可以用locastorage.getItem('isLogin')来取得登录信息然后判断:

function isLogin() {
    return localStorage.getItem('isLogin') == 1;
}

上面的代码看起来很好,其实也没啥大问题。不过当你多个地方都调用了它, 然后出现了如下需求: 登录状态的判断还要看另外一个状态(这个例子可能不太恰当,理解意思就好), 而这个状态需要通用调接口获取, 然后代码可能会是这样:

function isLoginAsync() {
    if (localStorage.getItem('isLogin') != 1) {
        return Promise.resolve(false);
    }

    // 到这来说明:localStorage.getItem('isLogin') == 1
    // 然后进行另一个状态的判断
    return new Promise(function(resolve, reject) {
        getLoginStatusFromServer().then(isLogin => {
            resolve(isLogin);
        });
    });
}

// 之前调用isLoginSync的位置可能会做出如下修改:
// function serviceFunc() {
// if (isLogin()) { /* some code */ }
// ...

async function serviceFunc() {
if (await isLoginAsync()) { /* some code */ }
// ...

有人会说, 这改起来也没啥,不难改。额, 确实不难, 不过可能真的调用的地方很多,怕改错。 而且如果只能用Promise呢,不能用async/await呢?那改起来就麻烦了。

await 同步代码会立即返回

function add(a, b) {
    console.log('add start:', +new Date);
    var s = a + b;
    console.log('add end:', +new Date);
    return s;
}

function addAsync(a, b) {
    return new Promise(function(resove, reject) {
        console.log('addAsync start:', +new Date);
        setTimeout(()=>{
            resove(a + b);
            console.log('addAsync end:', +new Date);
        }, 1000);
    });
}

async function f1() {
    let s1 = await addAsync(1,2);
    console.log("s1=%d", s1);
    let s2 = await add(3,4);
    console.log("s2=%d", s2);
}

f1();

// 输出:
// addAsync start: 1535375446468
// addAsync end: 1535375447470
// s1=3
// add start: 1535375447470
// add end: 1535375447470
// s2=7
f1();

从输出可以看到, 同步和异步加法在使用await如果,除了时间(异步等待)外,效果没什么差别。 这也就是说, 如果考虑到扩展,可以一开始就用异步的写法,避免后面改动过大。

串行Promise

function resolve(...args) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
             resolve(...args);
        }, 200);
    });
}

async function test() {
    for (var i = 0; i < 10; i++) {
        let res = await resolve(i * i);
        console.log(res);
    }
}

// 依次输出: 0, 1, 4, 16, ... 81
test();

欢迎补充指正!

你可能感兴趣的:(JavaScript)