ES6 语法中的 async 和 await
async 函数用法
async function f () {
return 1
}
f.then(i => i)
async function f () {
return Promise.resolve(1)
}
f.then(i => i)
由以上两例可以知道 ,async 函数中 return 后如果返回的是 promise 对象,那么返回的就直接是那个 promise 对象,如果是非 promise 对象,那么 async 函数会将其包裹为一个 promise 对象。
await 语句的使用
await 必须在 async 函数中使用
async function f (){
console.time('value');
let value = await new Promise((resolve, reject) => {
setTimeout( () => {resolve(1000);} , 1000)
})
console.log(value);
console.timeEnd('value');
}
使用了 await 之后会将 promise 包裹的数据解构,注意 await 必须在 async 函数中使用,Promise.resolve 使用 await 会导致报错。
使用的例子
async function showAvatar(){
// read our JSON
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();
// read github user
let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
let githubUser = await githubResponse.json();
// show the avatar
let img = document.createElement('img');
img.src = githubUser.avatar_url;
img.className = "promise-avatar-example";
document.body.append(img);
// wait 3 seconds
await new Promise((resolve, reject) => setTimeout(resolve, 3000));
img.remove();
return githubUser;
}
注意
- 不能在没有 async 函数包裹的情况下,使用 await 语句
- 所有的 thenable 的对象都可以使用 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 Waiter {
async wait() {
return await Promise.resolve(1);
}
}
new Waiter()
.wait()
.then(alert); // 1
Error handling
下面这些代码 介绍了如何在 async 函数中抛出异常:
async function f() {
await Promise.reject(new Error("Whoops!"));
}
这个和下面的意义是一样的
async function f() {
throw new Error("Whoops!");
}
还有下面
async function f() {
try {
let response = await fetch('http://no-such-url');
} catch(err) {
alert(err); // TypeError: failed to fetch
}
}
f();
自己的一些使用体会
下面两种用法, 为什么上面的有效,下面的无效
async function getTraces() {
let userPromises = [];
for (let index = 0; index < users.length; index++) {
const user = users[index];
userPromises[index] = await fetchGet(
'ip:port/' +
user.dscode +
'&userid=' +
user.userId +
'&' +
TIME
).then(res => {
return res.json();
});
}
return userPromises;
}
let userPromises = [];
userPromises = users.map(user => {
return await fetchGet(
'ip:port/' +
user.dscode +
'&userid=' +
user.userId +
'&' +
TIME
).then(res => {
return res.json();
});
})
因为第二个函数中 await 被包裹在了map 的匿名函数中导致不能使用
如何才能保证异步一个个执行await 语句呢
每一个 await 函数后面都传递的是未触发的 Promise, 并且保证每一个 resolve 都写在该函数中的异步流中
ES6 语法中的 async 和 await
async 函数用法
由以上两例可以知道 ,async 函数中 return 后如果返回的是 promise 对象,那么返回的就直接是那个 promise 对象,如果是非 promise 对象,那么 async 函数会将其包裹为一个 promise 对象。
await 语句的使用
await 必须在 async 函数中使用
使用了 await 之后会将 promise 包裹的数据解构,注意 await 必须在 async 函数中使用,Promise.resolve 使用 await 会导致报错。
使用的例子
注意
Error handling
下面这些代码 介绍了如何在 async 函数中抛出异常:
这个和下面的意义是一样的
还有下面
自己的一些使用体会
下面两种用法, 为什么上面的有效,下面的无效
因为第二个函数中 await 被包裹在了map 的匿名函数中导致不能使用
如何才能保证异步一个个执行await 语句呢
每一个 await 函数后面都传递的是未触发的 Promise, 并且保证每一个 resolve 都写在该函数中的异步流中