学习ES7异步和等待的简化

147 阅读2分钟

诺言一直是解决JavaScript "回调地狱 "问题的主要方法,但从ES6开始,现在ES7正在慢慢地将其隐藏起来,为asyncawait

目前,"回调地狱 "可以通过使用诸如async之类的库来缓解,或者通过使用由koa推广的生成器来缓解。但这两种方法都属于黑客/助手的范畴,只是掩盖了基本问题。

有了ES7,我们将能够以一种不那么黑的方式来编写我们的异步代码,就像它是同步的一样。

异步

下面是一个异步代码的例子。

async function run(){
    if(Math.round(Math.random())){
        return 'Success!';
    } else {
        throw 'Failure!';
    }
}

async 关键字允许我们使用await ,它保证了该函数将返回一个Promise ,其状态是已解决或已拒绝。当你从一个异步函数返回时,你将返回一个带有解析值的Promise 对象。要拒绝,就抛出一个错误,这将返回一个错误对象。

上面的代码块本质上与之相同。

function run(){
    if(Math.round(Math.random())){
        return Promise.resolve('Success!');
    }else{
        return Promise.reject('Failure!');
    }
}

我们可以采取任何函数,并通过添加async 关键字使其返回一个Promise 对象。下面是一个例子。

async function get(value){
    return value + 10;
}

Await

现在,await关键字。

在异步函数内部时,可以用await 关键字添加承诺返回的表达式。通过这样做,它将暂停函数的其余部分的执行,直到返回的承诺被解决或拒绝。请看这个简单的例子。

function op(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            if(Math.round(Math.random())){
                resolve('Success')
            }else{
                reject('Fail')
            }
        },2000)
    });
}

async function foo(){
    console.log('running')
    try {
        var message = await op();
        console.log(message)
    } catch(e) {
        console.log('Failed!', e);
    }
}

foo()

当你调用foo() ,它将等待2000毫秒,然后要么解决要么拒绝。注意这个try/get。现在我们可以捕捉错误了。

结论

总之,这是解决 "回调地狱 "的最好方法,没有不可捕捉的承诺错误和生成器黑客。ES7仍在开发中,但通过babel或traceur,今天就可以使用它了。