Bootstrap

JS中的aynsc和await

虽然async和await通常会在一起被提到,但是最好把它们分开,作为两个概念,更容易理解些。

况且使用async也不一定要使用await

async,await 是以更舒适的方式使用promise的一种特殊语法,相比promise它使代码更优雅。

ansync function

定义一个异步函数

async function f() {
    return 1;
}

它是异步执行的,它总是返回一个promise,返回的值被自动包装在一个resolved的promise中。它的行为就如同下面的代码

Promise.resolve(1)

异步函数中会返回一个包装后的promise对象,它对返回值的处理与Promisethen方法一样。

如下代码再通过then方法注册回调函数。

async function f() {
    return 1;
}

f().then((r)=>console.log(r));

console.log("==> end");//这个==> end在1之前输出

await关键字

如下语法:

let value = await promise;

关键字await让javascript引擎等待直到promise完成并返回结果。

它只能在async函数内工作。

async function f() {
    let p = new Promise((resolve,reject) => {
        setTimeout(()=>resolve("done!"),1000);
    });

    let r = await p

    console.log(r);
    console.log("===>end");
}

f()

这个函数在执行时,"暂停"在了await那一行,在等待Promise执行完后,才继续执行。可以看到输出结果是

===>end 在 done之后打印。

相比于promise.thenawait只是获取promise的结果的一个更优雅的语法,并且也更易于读写,所以它返回的还是一个包装后的promise对象,当然还可以再调用then,形成链式调用。

async function f() {
    return await new Promise((resolve,reject)=>{
        setTimeout(()=>resolve("done!"),1000);
    });
}

f().then((r)=>{
    console.log(r);
})

上面的代码等待一秒后再输出结果值。

作用

aynsc和await的作用就是简化Promise代码。

看下面的例子,通过Promise实现顺序的网络文件请求。

function ajax(url,sucessCb,failedCb) {
    //1.创建XMLHttpRequest对象
    var xmlHttp = new XMLHttpRequest();
    //2.发送请求
    xmlHttp.open('GET',url,true);
    xmlHttp.send();
    //3.服务端响应
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
            var obj = JSON.parse(xmlHttp.response);
            sucessCb && sucessCb(obj);
        } else if (xmlHttp.readyState === 4 && xmlHttp.status === 404) {
            failedCb && failedCb(xmlHttp.statusText);
        }
    }
}

function getPromise(url) {
    return new Promise((reslove,reject)=> {
        ajax(url,reslove,reject);
    })
}

getPromise('static/a.json').then(res=>{
    console.log(res);
    return getPromise('static/b.json');
}).then(res=>{
    console.log(res);
    return getPromise('static/c.json');
},err=>{
    console.log(err);
    return getPromise('static/d.json');
}).then(res=>{
    console.log(res);
})

通过aynsc和await来简化

async function getData() {
  const res1 = await request('static/a.json');
  console.log(res1);
  const res2 = await request('static/b.json');
  console.log(res2);
  const res3 = await request('static/c.json');
  console.log(res3);
}

参考资料:

https://zh.javascript.info/async-await

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;