es7异步 - async、await 让异步编程更简单

 

一、async  await 概念

 

  1. ECMAScript 2017 引入async函数,是generator 和 promises的语法糖,使异步代码更易于编写和阅读。通过使用它们,异步代码看起来更像是老式同步代码;

 2. 不需要附加 .then() 代码块到每个promise-based方法的结尾,你只需要在方法调用前添加 await 关键字,然后把结果赋给变量。

   await 关键字使JavaScript运行时暂停于此行,允许其他代码在此期间执行,直到异步函数调用返回其结果。

 3. 更少的.then()块来封装代码,同时它看起来很像同步代码,所以它非常直观。

 4. 想添加错误处理,可以将同步的 try...catch 结构和 async/await 一起使用

 

二、async  await 相关语法

 

async 函数

  • 声明一个async函数,是使用 async 关键字,把它放在函数声明之前,使其成为 async function。异步函数也就意味着该函数的执行,不会阻塞后面代码的执行。
  • async函数 返回的是一个 promise 对象,而不是直接返回值。无论函数内是否有await操作
  • 函数内部return返回的值,会成为then () 回调函数 的参数
  • 函数内部如果抛出错误,会被then的第二个参数 或者 catch捕获到。

   

// 语法

async
function fn1() {//.....} let fn2 = async funtion(){ //.....} let fn3 = async ()=>{//.....}

 

 将 async 关键字加到函数申明中,可以告诉它们返回的是 promise 对象,而不是直接返回值👇 

async function testAsync() {
    return 111;
}
console.log(testAsync()); // 返回结果是一个promise对象,而不是 111 
/***
 * Promise
 *   __proto__: Promise
 * [[PromiseStatus]]: "resolved"
 * [[PromiseValue]]: 111
 * 
 */
// async 封装的函数,正确调用方式:
testAsync().then(res => {
  console.log(res); // 111
})

 

await关键字

  • await 关键字不能单独使用, 只在异步函数里起作用。普通函数内会报错。(它可以放在任何异步的,基于 promise 的函数之前。它会暂停代码在该行上,直到 promise 完成,然后返回结果值。在暂停的同时,其他正在等待执行的代码就有机会执行了。)
  • 正常情况下,await 后是一个Promise对象, 返回该对象结果; 如果await后不是Promise,就直接返回对应的值
  • await 是在等待后面表达式的执行结果。需要等待await后面的函数 运行完并且有了返回结果 之后,才继续执行下面的代码,同步的效果。
  • 阻塞主函数的执行,直到后面的Promise函数返回结果

 

function testWait() {
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            console.log("testWait");
            resolve();
        }, 1000);
    })
}
async function testAwaitUse(){
    await testWait()
    console.log("hello");
    return 123;
    // 输出顺序:testWait,hello
    // 不使用await输出顺序:hello , testWait
}
// testAwaitUse();
console.log(testAwaitUse())

 

示例:

async function myFetch() {
   let response = await fetch('coffee.jpg');
   return await response.blob();
}

myFetch()
.then((blob)
=> {  let objectURL = URL.createObjectURL(blob);  let image = document.createElement('img');  image.src = objectURL;  document.body.appendChild(image); }) .catch((e) =>   console.log(e) );

 

三、Promise、generator、async

 

回忆Promise👇


 

 

改写为async写法👇

 

 

 

或以下写法👇

 

 

 

 

 

 

 

 

(二)、把 generator改造为 async方式

 

 

 

⚠️:不管加不加await, asycn函数返回的都是一个promise对象实例,值作为参数传递过去,then方法接收👇。

 

 

 


 

 

 

 

 

 综上,推荐第一种 并行写法。

 

 

文档: MDN Web Docs

 

posted @ 2020-07-15 16:03  CatherLee  阅读(199)  评论(0编辑  收藏  举报