再见,再见,承诺成立,回调怒气冲冲!👋🎉
您可能已经在JavaScript中遇到了Promises(如果您没有快速阅读本指南,请参见👍)。它们使您能够参与异步调用的完成。它们使链接异步操作甚至将它们分组在一起变得简单。有一个小缺点。在使用Promises时,语法并不总是最漂亮的。
引入异步 + 等待 🎉
对于TL; DR async
+ 营地中的人来说,它们await
是消耗您的Promise
s的语法糖。🍭它们有助于理解代码流。没有新概念,Promise
穿的是更好的鞋子down向下滚动以gist
获取⌨️
用代码🍰烘焙蛋糕
我们要烤蛋糕🍰百胜!要烤蛋糕,我们首先需要获取配料。抱歉,这是普通海绵sponge
- 牛油
- 面粉
- 糖
- 鸡蛋🥚
在我们的代码中,获取每种成分都需要异步操作。
例如,这是方法getButter
:
const getButter = () => new Promise((resolve, reject) => {
setTimeout(() => resolve('Butter'), 3000)
})
这些操作将成为getIngredients
方法的一部分。当我们烤蛋糕时,我们需要getIngredients
在混合之前调用,等等。
有诺言
假设我们需要链接每个异步操作。getIngredients
是一次一次在超市收集一种成分的旅程🛒
在大多数情况下,仅在操作相互依赖时才需要链接操作。例如,如果第二个操作需要第一个操作的返回值,依此类推。
在我们的示例中,可能一次只能将一个商品添加到购物篮中。这意味着我们需要一步一步地了解所有要素。请记住,此处的代码是假设的,并显示了Promises的使用😉
getIngredients
Promises看起来如何?certainly之前,我当然已经看过这样的嵌套Promises
const getIngredients = () => new Promise((resolve, reject) => {
getButter().then((butter) => {
updateBasket(butter)
getFlour().then((flour) => {
updateBasket(flour)
getSugar().then((sugar) => {
updateBasket(sugar)
getEggs().then((eggs) => {
updateBasket(eggs)
resolve(basket)
})
})
})
})
})
这行得通,但看起来并不好with使用Promise链看起来会更好。
const getIngredients = () => new Promise((resolve, reject) => {
getButter()
.then((butter) => {
updateBasket(butter)
return getFlour()
})
.then((flour) => {
updateBasket(flour)
return getSugar()
})
.then((sugar) => {
updateBasket(sugar)
return getEggs()
})
.then((eggs) => {
updateBasket(eggs)
resolve(basket)
})
})
如果我们在网上购物,我们将使用Promise.all
🤓
const getIngredients = () => new Promise((resolve, reject) => {
Promise.all([
getButter(),
getFlour(),
getSugar(),
getEggs(),
]).then((ingredients) => resolve(ingredients))
})
用async + await整理它
让我们撒些语法糖🍭要使用await
关键字,必须首先将一个方法声明为与async
关键字异步。请务必注意,async
方法将始终返回Promise
。这意味着无需返回Promise
🎉
让我们声明getIngredients
为异步
const getIngredients = async () => {}
现在我们如何使这些Promise
消费看起来更整洁?该await
关键字允许我们等待Promise
并定义的返回值的变量Promise
。让我们将糖应用到getIngredients
。
const getIngredients = async () => {
const butter = await getButter()
const flour = await getFlour()
const sugar = await getSugar()
const eggs = await getEggs()
return [
butter,
flour,
sugar,
eggs,
]
}
哇!cleaner那是多少清洁工?
使用async
和await
使我们的代码具有程序性和全面性。它看起来更干净,功能完全相同。重要的是要记住,我们并没有取代Promises,而是仍在使用它们。现在,我们将它们与新的更干净的语法一起使用。
是的,这也适用Promise.all
。因此,如果我们在线购物,我们的代码将变得更小。
const getIngredients = async () => {
const ingredients = await Promise.all([
getButter(),
getFlour(),
getSugar(),
getEggs(),
])
return ingredients
}
甚至
const getIngredients = async () =>
await Promise.all([getButter(), getFlour(), getSugar(), getEggs()]);
等待一个不承诺
如果您的价值await
不是Promise
呢?在我们的示例中,异步函数在a String
之后返回a setTimeout
。
const egg = await 🥚
不会有任何错误,该值成为解决Promise
😅
那拒绝呢?
到目前为止,我们已经处理了幸福的道路path但是,如果Promise
拒绝,情况又如何呢?
例如,如果没有库存,该怎么办?我们的异步函数getEggs
将拒绝,并可能出现错误。
为了适应这一点,简单的try
/ catch
语句就可以解决问题。
const getIngredients = async () => {
try {
const butter = await 'Butter'
const flour = await getFlour()
const sugar = await getSugar()
const eggs = await getEggs()
return [
butter,
flour,
sugar,
eggs,
]
} catch(e) { return e }
}
消费我们的功能并烤蛋糕🍰
如果您到此为止,我们已经getIngredients
使用新的async
+ await
关键字创建了函数。其余的可能是什么样子?
const bakeACake = async () => {
try {
// get the ingredients
const ingredients = await getIngredients()
// mix them together
const cakeMix = await mix(ingredients)
// put in oven on 180C, gas mark 4for 20-25 minutes
const hotCake = await cook(cakeMix)
// allow to stand before serving
const cake = await stand(hotCake)
return cake
} catch (e) { return e }
}
比替代品清洁得多
const bakeACake = () => new Promise((resolve, reject) => {
getIngredients
.then((ingredients) => {
return mix(ingredients)
})
.then((cakeMix) => {
return cook(cakeMix)
})
.then((hotCake) => {
return stand(hotCake)
})
.then((cake) => resolve(cake))
.catch((e) => reject(e))
})
而已!在5分钟内异步+烘烤蛋糕🍰
如果您已经了解了这么多,感谢您阅读😃我整理了要点和一些可能的示例代码,可以在下面看到这些代码以及async
+ 上的更多资源await
。
重要的外卖⚠️;
async
函数将始终返回Promise
await
在大多数情况下,将针对一个Promise
或一组Promise
s- 使用
try
/catch
语句处理任何潜在的错误👍 - 我们还没有谈到这一点,但你可以
await
的await
。制作fetch
要求,您可能会await
请求,然后await
该json
功能。
const data = await (await fetch(`${dataUrl}`)).json()
与往常一样,任何问题或建议,请随时给我回复或鸣叫me!一定要关注我的社交活动😎
//用于库存检查的助手功能 | |
const doIfHaveIt =()=> 数学。随机()> 0.1 | |
//获得不同成分的样板函数 | |
const getButter =()=> 新的 Promise((resolve,reject)=> { | |
setTimeout(doIfHaveIt()? resolve(‘黄油‘): 拒绝(‘对不起,没有黄油‘),1000) | |
}) | |
const getFlour =()=> 新的 Promise((resolve,reject)=> { | |
setTimeout(doIfHaveIt()? resolve(‘面粉‘): 拒绝(‘对不起,没有面粉‘),1000) | |
}) | |
const getSugar =()=> 新的 Promise((resolve,reject)=> { | |
setTimeout(doIfHaveIt()? resolve(‘糖‘): 拒绝(‘对不起,没有糖‘),1000) | |
}) | |
const getEggs =()=> 新的 Promise((resolve,reject)=> { | |
setTimeout(doIfHaveIt()? resolve(‘鸡蛋‘): 拒绝(‘对不起,没有鸡蛋‘),1000) | |
}) | |
const getIngredientsFromTheSuperMarket = 异步()=> { | |
尝试 { | |
const butter = 等待 getButter() | |
常量 面粉 = 等待 getFlour() | |
const sugar = 等待 getSugar() | |
常量 鸡蛋 = 等待 getEggs() | |
返回 [ | |
牛油, | |
面粉, | |
糖, | |
蛋, | |
] | |
} 抓住(e){ 返回 e} | |
} | |
const getIngredientsOnline = async()=> { | |
尝试 { | |
返回 等待 承诺。全部([ | |
getButter(), | |
getFlour(), | |
getSugar(), | |
getEggs(), | |
]) | |
} 抓住(e){ 返回 e} | |
} | |
//返回字符串的样板异步函数 | |
const mix = 异步(配料)=> ‘ Cake Mix ‘ | |
const cook = 异步(cakeMix)=> ‘ Hot Cake ‘ | |
const stand = 异步(hotCake)=> ‘ 🍰 ‘ | |
const bakeACake = 异步()=> { | |
const 成分 = 等待 getIngredientsOnline() | |
const cakeMix = 等待 混合(成分) | |
const hotCake = 等待 厨师(cakeMix) | |
const cake = 等待 站(hotCake) | |
回报蛋糕 | |
} | |
//创建一个新鲜的蛋糕并将其记录在回调中 | |
const freshCake = bakeACake()。然后((饼)=> 控制台。信息(饼)) |