async/await是一种方便使用promise的特殊语法。javascript
函数前面的async表示:此函数将会返回一个promise,若是函数返回的不是promise,将会包装成一个已经resolved的promise。java
async function f() { return 1; } f().then(alert); // 1 // 至关于下面的写法 async function f() { return Promise.resolve(1); } f().then(alert); // 1 复制代码
await只在async函数中有效,普通函数中使用await会报语法错误。let value = await promise;
表示让JavaScript引擎等待直到 promise 完成并返回结果。这个行为不会耗费 CPU 资源,由于引擎能够同时处理其余任务:执行其余脚本,处理事件等。promise
async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); let result = await promise; // 等待直到 promise resolved后拿到result继续往下执行 alert(result); // "done!" } f(); 复制代码
await能够接收Thenable对象(具备 then 方法的对象)并调用then方法,并将resolve,reject 做为参数传入。而后await等到这两个方法中的某个被调用,再处理获得的结果。markdown
class Thenable { constructor(num) { this.num = num; } then(resolve, reject) { setTimeout(() => resolve(this.num * 2), 1000); } }; async function f() { // 等待 1 秒, result 变为 2 let result = await new Thenable(1); alert(result); } f(); 复制代码
若是想定义一个 async 的类方法,在方法前面添加 async 就能够了:async
class Waiter { async wait() { return await Promise.resolve(1); } } new Waiter().wait().then(alert); // 1 复制代码
若是一个promise被resolved,await promise返回的就是其结果。 若是一个promise被rejected,就会抛出一个错误,就像在那一行有个 throw 语句那样。函数
async function f() { await Promise.reject(new Error("Whoops!")); } // 至关于: async function f() { throw new Error("Whoops!"); } 复制代码
能够用 try..catch 来捕获上面的错误,就像对通常的 throw 语句那样:oop
async function f() { try { let response = await fetch('http://no-such-url'); } catch(err) { alert(err); // TypeError: failed to fetch } } f(); 复制代码
若是不使用 try..catch,由f() 产生的 promise 就会被reject,能够在函数调用后添加 .catch 来处理错误。若是没处理错误能够使用全局的unhandledrejection事件来捕获。fetch
async function f() { let response = await fetch('http://no-such-url'); } // f() 变为一个被reject的 promise f().catch(alert); // TypeError: failed to fetch // (*) 复制代码
当须要等待多个promise时,能够用Promise.all搭配async/await使用:this
async () => { let results = await Promise.all([ fetch(url1), fetch(url2), ... ]); } 复制代码
若是发生错误,也会正常传递:先从失败的 promise 传到 Promise.all,而后变成咱们能用 try..catch 处理的异常。url
Async/await 是基于 promise 的,因此它内部使用相同的微任务队列,而且相对宏任务来讲具备更高的优先级。
async function f() { return 1; } (async () => { setTimeout(() => alert('timeout'), 0); // 3 await f(); // 1 alert('await'); // 2 })(); 复制代码
在一个普通的函数中,如何调用另外一个 async 函数而且拿到返回值?使用then,由于async函数返回一个settled promise。
async function wait() { await new Promise(resolve => setTimeout(resolve, 1000)); return 10; } (function() { wait().then((value) => alert(value)); })();复制代码