20分钟带你掌握JS Promise和Async/Await

一般在开发中,查询网络 API 操作时往往是比较耗时的,这意味着可能需要一段时间的等待才能获得响应 。因此,为了避免程序在请求时无响应的情况,异步编程就成为了开发人员的一项基本技能 。
在 JAVAScript 中处理异步操作时,通常我们经常会听到 "Promise "这个概念 。但要理解它的工作原理及使用方法可能会比较抽象和难以理解 。
那么,在本文中我们将会通过实践的方式让你能更快速的理解它们的概念和用法,所以与许多传统干巴巴的教程都不同,我们将通过以下四个示例开始:

  • 示例1:用生日解释Promise的基础知识
  • 示例2:一个猜数字的游戏
  • 示例3:从Web API中获取国家信息
  • 示例4:从Web API中获取一个国家的周边国家列表
示例1:用生日解释Promise基础知识首先,我们先来看看Promise的基本形态是什么样的 。
Promise执行时分三个状态:pending(执行中)、fulfilled(成功)、rejected(失败) 。
new Promise(function(resolve, reject) {if (/* 异步操作成功 */) {resolve(value); //将Promise的状态由padding改为fulfilled} else {reject(error); //将Promise的状态由padding改为rejected}})实现时有三个原型方法then、catch、finally
promise.then((result) => {//promise被接收或拒绝继续执行的情况}).catch((error) => {//promise被拒绝的情况}).finally (() => {//promise完成时,无论如何都会执行的情况})基本形态介绍完成了,那么我们下面开始看看下面的示例吧 。
用户故事:我的朋友Kayo答应在两周后在我的生日Party上为我做一个蛋糕 。
如果一切顺利且Kayo没有生病的话,我们就会获得一定数量的蛋糕,但如果Kayo生病了,我们就没有蛋糕了 。但不论有没有蛋糕,我们仍然会开一个生日Party 。
所以对于这个示例,我们将如上的背景故事翻译成JS代码,首先让我们先创建一个返回Promise的函数 。
const onMyBirthday = (isKayoSick) => {return new Promise((resolve, reject) => {setTimeout(() => {if (!isKayoSick) {resolve(2);} else {reject(new Error("I am sad"));}}, 2000);});};在JavaScript中,我们可以使用new Promise()创建一个新的Promise,它接受一个参数为:(resolve,reject)=>{} 的函数 。
在此函数中,resolve和reject是默认提供的回调函数 。让我们仔细看看上面的代码 。
当我们运行onMyBirthday函数2000ms后 。
  • 如果Kayo没有生病,那么我们就以2为参数执行resolve函数
  • 如果Kayo生病了,那么我们用new Error("I am sad")作为参数执行reject 。尽管您可以将任何要拒绝的内容作为参数传递,但建议将其传递给Error对象 。
现在,因为onMyBirthday()返回的是一个Promise,我们可以访问then、catch和finally方法 。我们还可以访问早些时候在then和catch中使用传递给resolve和reject的参数 。
让我们通过如下代码来理解概念,相信通过这个例子你能了解Promise的基本概念 。
如果Kayo没有生病
onMyBirthday(false).then((result) => {console.log(`I have ${result} cakes`); // 控制台打印"I have 2 cakes"}).catch((error) => {console.log(error); // 不执行}).finally(() => {console.log("Party"); // 控制台打印"Party"});如果Kayo生病
onMyBirthday(true).then((result) => {console.log(`I have ${result} cakes`); // 不执行}).catch((error) => {console.log(error); // 控制台打印"我很难过"}).finally(() => {console.log("Party"); // 控制台打印"Party"});示例2:一个猜数字的游戏基本需求:
  • 用户可以输入任意数字
  • 系统从1到6中随机生成一个数字
  • 如果用户输入数字等于系统随机数,则给用户2分
  • 如果用户输入数字与系统随机数相差1,给用户1分,否则,给用户0分
  • 用户想玩多久就玩多久
【20分钟带你掌握JS Promise和Async/Await】对于上面的需求,我们首先创建一个enterNumber函数并返回一个Promise:
const enterNumber = () => {return new Promise((resolve, reject) => {// 从这开始编码});};我们要做的第一件事是向用户索要一个数字,并在1到6之间随机选择一个数字:
const enterNumber = () => {return new Promise((resolve, reject) => {const userNumber = Number(window.prompt("Enter a number (1 - 6):")); // 向用户索要一个数字const randomNumber = Math.floor(Math.random() * 6 + 1); // 选择一个从1到6的随机数});};当用户输入一个不是数字的值 。这种情况下,我们调用reject函数,并抛出错误:


推荐阅读