javascript 异步
If you’re familiar with promises in JavaScript the .then() method of structuring them can still feel a bit like working with call back functions.
如果您熟悉JavaScript中的.then() ,则构造它们的.then()方法仍然会有点像使用回调函数。
Async functions and the await keyword act like syntactic sugar on top of promises, making asynchronous code both easier to read and write.
异步函数和await 关键字在promise的基础上就像语法糖一样,使异步代码更易于读写。
Async
异步
We put the async keyword in front of a function declaration to turn it into an async function. An async function expects the possibility of the await keyword being used within it to invoke a block of asynchronous code.
我们将async关键字放在函数声明的前面,以将其转换为异步函数。 异步函数期望在其中使用await关键字来调用异步代码块的可能性。
let hello = async function() {
return 'hello'
};hello();
In the above example, hello is an async function.
在上面的示例中, hello是异步函数。
Await
等待
The await keyword is only valid inside of an async function. If used outside it will generate a SyntaxError. Awaiting on a promise, the await keyword pauses the execution of the surrounding async function until that promise is either fulfilled or rejected. await also unwraps the promise giving us access to its fulfilled value. There can be multiple await statements within a single async function.
await关键字仅在异步函数内部有效。 如果在外部使用它将生成SyntaxError 。 在等待诺言时,关键字await暂停周围异步函数的执行,直到实现或拒绝诺言为止。 await也解开了诺言,使我们能够实现其实现的价值。 一个异步函数中可以有多个await语句。
async function hi() {
return 'hi!';}const greeting = hello();
console.log(greeting); // Promise {<fulfilled>: "hello"}
Returned in the above example is a promise.
在上面的示例中返回的是一个承诺。
How can we use async-await?
我们如何使用异步等待?
In the below example, we declare a function that will return a promise that resolves to “Cake Time!!! 🧁” after two seconds have passed. We then declare an async function and await for the promise to be resolved before logging the message to the console.
在下面的示例中,我们声明一个函数,该函数将返回解析为“ Cake Time !!!”的promise。 two”两秒钟后。 然后,我们声明一个异步函数,并在将消息记录到控制台之前等待承诺被解决。
function makeCake() {
return new Promise(function (resolve) {
setTimeout(() => {resolve('Cake Time!!! 🧁');
}, 2000);
});
}async function message() {const message = await makeCake();
console.log('Message:', message);
}message(); // Message: Cake Time!!! 🧁
We can see the power of async when there are multiple steps involved.
当涉及多个步骤时,我们可以看到async的力量。
function character() {
return new Promise(function (resolve) {
setTimeout(() => {resolve('Colonel Mustard,');
}, 200);
});
}function room() {
return new Promise(function (resolve) {
setTimeout(() => {resolve('in the library,');
}, 500);
});
}function weapon() {
return new Promise(function (resolve) {
setTimeout(() => {resolve('with the candlestick');
}, 300);
});
}async function cluedo() {const who = await character();const where = await room();const using = await weapon();
console.log(`${ who } ${ where } ${ using }`);
}cluedo(); // Colonel Mustard, in the library, with the candlestick
With the above example, each step is carried out sequentially, with each additional function waiting for the one before to resolve or reject before continuing. After one second, we log “Colonel Mustard, in the library, with the candlestick” to the console.
在上述示例中,每个步骤都是按顺序执行的,每个附加功能都在等待之前的一个功能解决或拒绝,然后再继续。 一秒钟后,我们将“带烛台的库尔德芥末酱”登录到控制台。
If we want the steps to happen in parallel, we use the Promise.all() method. This method returns an array of the resolved values once all of the passed-in promises have been resolved. Remember that using this method means that if any of the input promises reject, then it will immediately reject.
如果我们想在平行发生的步骤,我们使用的 Promise.all() 方法 。 一旦所有传入的承诺均已解决,此方法将返回一个解析值数组。 请记住,使用此方法意味着如果任何输入的Promise都会被拒绝,那么它将立即被拒绝。
// ...async function cluedo() {const who = await character();const where = await room();const using = await weapon(); const whoDidIt = await Promise.all([character(), room(), weapon()]) console.log(whoDidIt); // (3) ["Colonel Mustard,", "in the library,", "with the candlestick"] console.log(`${ who } ${ where } ${ using }`); // Colonel Mustard, in the library, with the candlestick}cluedo();
As the above all run in parallel, we output to the console after just 500ms — the longest duration of one of the passed-in promises.
由于上述所有操作都是并行运行的,因此我们仅在500毫秒(这是传入承诺之一的最长持续时间)后输出到控制台。
Error handling
错误处理
A useful feature of async functions is that error handling is also done synchronously. We use try catch statements to handle our errors.
异步功能的一个有用功能是错误处理也可以同步完成。 我们使用try catch 语句来处理错误。
We can demonstrate this by creating a promise that will reject only some of the time.
我们可以通过创建仅会拒绝某些时间的承诺来证明这一点。
function headsOrTails() {
return new Promise((resolve, reject) => {const value = Math.round(Math.random() * 1);
value ? resolve('Yay, heads!!!') : reject('Bad luck, tails');
console.log(value);
});
}async function outcome() {
try {const outcome = await headsOrTails();
console.log(outcome);
} catch(error) {
console.log(error);
}
}outcome(); // Bad luck, tails
outcome(); // Bad luck, tails
outcome(); // Yay, heads!!!
outcome(); // Yay, heads!!!
outcome(); // Yay, heads!!!
outcome(); // Bad luck, tails
outcome(); // Bad luck, tails
outcome(); // Yay, heads!!!
As async functions always return a promise, so we can also deal with the errors using just a catch statement.
由于异步函数总是返回promise,因此我们也可以仅使用catch语句来处理错误。
async function test() {const promise = Promise.reject(new Error('Oops'));const error = await promise.catch(error => error);
console.log(error.message);
}test(); // Oops
Summary
摘要
- Async functions return a promise
- Using the async keyword before a function allows await to be used inside of the function 使用async关键字前一功能允许await是功能的使用的内部
- await causes JavaScript to wait until the promise has settled await使JavaScript等待,直到诺言完成
- await unwraps the promise giving us access to its fulfilled value await兑现承诺,使我们能够实现其实现的价值
- We use try catch to handle errors, but can use a catch statement on its own 我们使用try catch处理错误,但是可以单独使用catch语句