WEB程序员笔记

一个前端开发工程师的个人博客

在5分钟内理解JavaScript的Async + Await

再见,再见,承诺成立,回调怒气冲冲!👋🎉

您可能已经在JavaScript中遇到了Promises(如果您没有快速阅读本指南,请参见👍)。它们使您能够参与异步调用的完成。它们使链接异步操作甚至将它们分组在一起变得简单。有一个小缺点。在使用Promises时,语法并不总是最漂亮的。

引入异步 + 等待 🎉

对于TL; DR async + 营地中的人来说,它们await是消耗您的Promises的语法糖。🍭它们有助于理解代码流。没有新概念,Promise穿的是更好的鞋子down向下滚动以gist获取⌨️

用代码🍰烘焙蛋糕

我们要烤蛋糕🍰百胜!要烤蛋糕,我们首先需要获取配料。抱歉,这是普通海绵sponge

  • 牛油
  • 面粉
  • 鸡蛋🥚

在我们的代码中,获取每种成分都需要异步操作。

例如,这是方法getButter

const getButter = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve('Butter'), 3000)
})

这些操作将成为getIngredients方法的一部分。当我们烤蛋糕时,我们需要getIngredients在混合之前调用,等等。

有诺言

假设我们需要链接每个异步操作。getIngredients是一次一次在超市收集一种成分的旅程🛒

在大多数情况下,仅在操作相互依赖时才需要链接操作。例如,如果第二个操作需要第一个操作的返回值,依此类推。

在我们的示例中,可能一次只能将一个商品添加到购物篮中。这意味着我们需要一步一步地了解所有要素。请记住,此处的代码是假设的,并显示了Promises的使用😉

getIngredientsPromises看起来如何?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那是多少清洁工?

使用asyncawait使我们的代码具有程序性和全面性。它看起来更干净,功能完全相同。重要的是要记住,我们并没有取代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将拒绝,并可能出现错误。

为了适应这一点,简单的trycatch语句就可以解决问题。

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使用新的asyncawait关键字创建了函数。其余的可能是什么样子?

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或一组Promises
  • 使用trycatch语句处理任何潜在的错误👍
  • 我们还没有谈到这一点,但你可以awaitawait。制作fetch要求,您可能会await请求,然后awaitjson功能。
const data = await (await fetch(`${dataUrl}`)).json()

与往常一样,任何问题或建议,请随时给回复或鸣叫me!一定要关注我的社交活动😎

//用于库存检查的助手功能
const doIfHaveIt =()=> 数学随机()> 0.1
//获得不同成分的样板函数
const getButter =()=> 新的 Promise((resolvereject=> {
setTimeoutdoIfHaveIt() resolve黄油 拒绝对不起,没有黄油),1000
})
const getFlour =()=> 新的 Promise((resolvereject=> {
setTimeoutdoIfHaveIt() resolve面粉 拒绝对不起,没有面粉),1000
})
const getSugar =()=> 新的 Promise((resolvereject=> {
setTimeoutdoIfHaveIt() resolve 拒绝对不起,没有糖),1000
})
const getEggs =()=> 新的 Promise((resolvereject=> {
setTimeoutdoIfHaveIt() 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()。然后((=> 控制台信息(饼))

更多资源

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注