理解 es7 async await

2,629 阅读4分钟

说明

  • 开始进行 react 项目,需要用到 es7 的 async 和 await 来替代以前的 promise 的方法q请求接口。在这里学习一下和大家一起分享。
  • 适用:es6,es7初学者

一 理解 promise

  • 需要明白 es7 的 await 和 async 是什么我们想要看看 promise 是什么?

promise 的使用

老式的处理方法

  • 在讲 promise 之前我们也需要先了解一下,我们平时在处理接口成功和失败的时候的处理方法如下。👇
function successCallback(result) {
  console.log("It succeeded with " + result);
}

function failureCallback(error) {
  console.log("It failed with " + error);
}

doSomething(successCallback, failureCallback);

promise替代了下面这种旧式的函数,这种旧式函数需要两个回调函数,并最终调用处理成功事件或者处理失败事件的回调函数

用 promise 处理异步

  • 一个 Promise 就是一个代表了异步操作最终完成或者失败的对象,新式函数返回一个你可以直接绑定回调函数的promise对象,来代替上面👆那种旧式的函数形式如下👇:
const promise = doSomething(); 
promise.then(successCallback, failureCallback);

// 当然你可以简单一点
doSomeThing().then(successCallback,failureCallback)

promise 链式调用

  • 如果我们有多个异步操作,和需要在一个请求成功后再请求其他的接口。以前我们是这样做的
doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('Got the final result: ' + finalResult);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

这就是我们熟知的回调地狱

  • 一些常见的需求我们不得不连续进行两个或者跟多的异步操作和请求,每一个请求都需要在上个请求的成功的执行之后进行。我们可以通过 promise chain 来完成这种需求。
doSomething().then(function(result) {
  return doSomethingElse(result);
})
.then(function(newResult) {
  return doThirdThing(newResult);
})
.then(function(finalResult) {
  console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);

避免了回调地狱我们现在这样处理


我们花了些时间了解 promise 做铺垫,下面来了解 async 和await 的使用

二 async function

async 返回值

  • async用于定义一个异步函数,该函数返回一个Promise。

await

  • await 操作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。

概况

  • 在 es7 的 draft 中提出 async 和 await来进一步的解决异步函数的问题。
  • async function 声明将定义一个返回 AsyncFunction 对象的异步函数。

你还可以使用 异步函数表达式 来定义异步函数。

  • demo
function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  var result = await resolveAfter2Seconds();
  console.log(result);
  // expected output: "resolved"
}

asyncCall();

详解👆的 demo

  • 当调用一个 async 函数时,会返回一个 Promise 对象。当这个 async 函数返回一个值时,Promiseresolve 方法会负责传递这个值;当 async 函数抛出异常时,Promisereject 方法也会传递这个异常值。
  • async 函数中可能会有 await 表达式,这会使 async 函数暂停执行,等待表达式中的 Promise 解析完成后继续执行 async 函数并返回解决结果。

async/await的用途是简化使用 promises 异步调用的操作,并对一组 Promises执行某些操作。正如Promises类似于结构化回调,async/await类似于组合生成器和 promises。

用 async 改写 promise

  • promise chain
function getProcessedData(url) {
  return downloadData(url) // returns a promise
    .catch(e => {
      return downloadFallbackData(url)  // returns a promise
        .then(v => {
          return processDataInWorker(v); // returns a promise
        }); 
    })
    .then(v => {
      return processDataInWorker(v); // returns a promise
    });
}
  • async function
async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url); 
  } catch (e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

注意,在上述示例中,return 语句中没有 await 操作符,因为 async function 的返回值将隐式传递给 Promise.resolve。

写法

  • 现在我们这样的来书写异步请求
const signup = async () => {
            try {
                const resp = await signUp(parmas);
                doSometing(resp);
            } catch (error) {
                alert(error);
            }
        }
    };

async 函数异常

  • 我们直接在async函数中抛出一个异常,由于返回的是一个Promise,因此,这个异常可以调用返回Promise的catch()方法捕捉到。
let sayHi = async functionsayHi(){
    throw new Error('出错了');
}
sayHi().then(result=> {
    console.log(result);
}).catch(err=> {
    console.log(err.message);   //出错了
});
  • 和Promise链的对比:

我们的async函数中可以包含多个异步操作,其异常和Promise链有相同之处,如果有一个Promise被reject()那么后面的将不会再进行。

引用

mdn promise&async function