Async/await

async/await是一种用来处理Promise的特殊语法,同时给人的感觉又非常优雅。

Async 函数

我们先从async开始:

async function f() {
  return 1;
}

在函数前的async表示该函数总是返回一个Promise。当代码中没有返回Promise时,js会自动封装好一个Promise返回该值。

例如,上面的代码返回一个Promise,结果为1:

async function f() {
  return 1;
}

f().then(alert); // 1

特地返回一个Promise

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

所以说async函数总是返回Promise。接下来的await关键字更酷。

Await 关键字

// 只在async函数里面才有用
let value = await promise;

await用来使Javascript等待Promise对象执行。如果await的是 promise对象会造成异步函数停止执行并且等待Promiseresolve, 如果等的是正常的表达式则立即执行。
看下面的例子:

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

    let result = await promise; // wait till the promise resolves (*)

    alert(result); // "done!"
}

其实async/await差不多就是Promise.then()更优雅,可读性更强的写法。

几个需要注意的点

  • 在普通的函数里不能使用await
    如果在没有async声明的函数使用await就会报错。
function f() {
  let promise = Promise.resolve(1);
  let result = await promise; // Syntax error
}
  • thenable对象
    Promise.then一样,await也可以使用thenable对象(有可调用的then方法)。例如一个对象可能并不是Promise, 但有then方法可以调用,就可以使用await了。
class Thenable {
  constructor(num) {
    this.num = num;
  }
  then(resolve, reject) {
    alert(resolve); // function() { native code }
    // resolve with this.num*2 after 1000ms
    setTimeout(() => resolve(this.num * 2), 1000); // (*)
  }
};

async function f() {
  // waits for 1 second, then result becomes 2
  let result = await new Thenable(1);
  alert(result);
}

f();
  • class里使用
class Waiter {
  async wait() {
    return await Promise.resolve(1);
  }
}

new Waiter()
  .wait()
  .then(alert); // 1

异常处理

async function f() {
  await Promise.reject(new Error("Whoops!"));
}
// 一样的
async function f() {
  throw new Error("Whoops!");
}

try..catch

async function f() {

  try {
    let response = await fetch('http://no-such-url');
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();
async function f() {

  try {
    let response = await fetch('/no-user-here');
    let user = await response.json();
  } catch(err) {
    // catches errors both in fetch and response.json
    alert(err);
  }
}

f();
async function f() {
  let response = await fetch('http://no-such-url');
}

// f() becomes a rejected promise
f().catch(alert); // TypeError: failed to fetch // (*)

Promise.all搭配使用

// wait for the array of results
let results = await Promise.all([
  fetch(url1),
  fetch(url2),
  ...
]);

总结

在函数前面的async关键字有两个作用:

  • 让函数返回Promise对象
  • 在函数中可以使用await

await用来使Javascript等待Promise对象的执行

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容