es6学习4:async和await

匿名 (未验证) 提交于 2019-12-03 00:13:02

async

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

function setNumAdd(n) {             return new Promise((resolve,reject) =>{                 setTimeout( ()=>{                     n +=1;                     resolve(n)                 },1000)             })         }          function setNumSub(n) {             return new Promise((resolve,reject) =>{                 setTimeout( ()=>{                     n -=1;                     resolve(n)                 },1000)             })         }          async function d(n) {             const w1 = await setNumAdd(n);             const w2 = await setNumSub(n);             return w1+w2         }         d(10).then( v=>{             console.log(v)  //10         })

 

async函数返回一个 Promise 对象。async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function f() {   return 'hello world'; }  f().then(v => console.log(v)) // "hello world"

 

async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

async function f() {   throw new Error('出错了'); }  f().then(   v => console.log(v),   e => console.log(e) )  //等同于 f().then( v=> console.log(v)).catch( e=>console.log(e)) // Error: 出错了

 

await

正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

async function f() {   // 等同于   // return 123;   return await 123; }  f().then(v => console.log(v)) // 123

 

任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

async function f() {   await Promise.reject('出错了');   await Promise.resolve('hello world'); // 不会执行 }

上面代码中,第二个await语句是不会执行的,因为第一个await语句状态变成了reject

有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

async function f() {   try {     await Promise.reject('出错了');   } catch(e) {   }   return await Promise.resolve('hello world'); }  f() .then(v => console.log(v)) // hello world

另一种方法是await后面的 Promise 对象再跟一个catch方法,处理前面可能出现的错误

async function f() {   await Promise.reject('出错了')     .catch(e => console.log(e));   return await Promise.resolve('hello world'); }  f() .then(v => console.log(v)) // 出错了 // hello world 错误处理

 

 

如果有多个await命令,可以统一放在try...catch结构中。

async function main() {   try {     const val1 = await firstStep();     const val2 = await secondStep(val1);     const val3 = await thirdStep(val1, val2);      console.log('Final: ', val3);   }   catch (err) {     console.error(err);   } }

 

let foo = await getFoo(); let bar = await getBar();

多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。

上面代码中,getFoogetBar是两个独立的异步操作(即互不依赖),被写成继发关系。这样比较耗时,因为只有getFoo

完成以后,才会执行getBar,完全可以让它们同时触发。

// 写法一 let [foo, bar] = await Promise.all([getFoo(), getBar()]);  // 写法二 let fooPromise = getFoo(); let barPromise = getBar(); let foo = await fooPromise; let bar = await barPromise;

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!