游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

20分钟带你掌握JSPromise和AsyncAwait

  一般在开发中,查询网络API操作时往往是比较耗时的,这意味着可能需要一段时间的等待才能获得响应。因此,为了避免程序在请求时无响应的情况,异步编程就成为了开发人员的一项基本技能。
  在JavaScript中处理异步操作时,通常我们经常会听到Promise这个概念。但要理解它的工作原理及使用方法可能会比较抽象和难以理解。
  那么,在本文中我们将会通过实践的方式让你能更快速的理解它们的概念和用法,所以与许多传统干巴巴的教程都不同,我们将通过以下四个示例开始:示例1:用生日解释Promise的基础知识示例2:一个猜数字的游戏示例3:从WebAPI中获取国家信息示例4:从WebAPI中获取一个国家的周边国家列表示例1:用生日解释Promise基础知识
  首先,我们先来看看Promise的基本形态是什么样的。
  Promise执行时分三个状态:pending(执行中)、fulfilled(成功)、rejected(失败)。newPromise(function(resolve,reject){if(异步操作成功){resolve(value);将Promise的状态由padding改为fulfilled}else{reject(error);将Promise的状态由padding改为rejected}})
  实现时有三个原型方法then、catch、finallypromise。then((result){promise被接收或拒绝继续执行的情况})。catch((error){promise被拒绝的情况})。finally((){promise完成时,无论如何都会执行的情况})
  基本形态介绍完成了,那么我们下面开始看看下面的示例吧。
  用户故事:我的朋友Kayo答应在两周后在我的生日Party上为我做一个蛋糕。
  如果一切顺利且Kayo没有生病的话,我们就会获得一定数量的蛋糕,但如果Kayo生病了,我们就没有蛋糕了。但不论有没有蛋糕,我们仍然会开一个生日Party。
  所以对于这个示例,我们将如上的背景故事翻译成JS代码,首先让我们先创建一个返回Promise的函数。constonMyBirthday(isKayoSick){returnnewPromise((resolve,reject){setTimeout((){if(!isKayoSick){resolve(2);}else{reject(newError(Iamsad));}},2000);});};
  在JavaScript中,我们可以使用newPromise()创建一个新的Promise,它接受一个参数为:(resolve,reject){}的函数。
  在此函数中,resolve和reject是默认提供的回调函数。让我们仔细看看上面的代码。
  当我们运行onMyBirthday函数2000ms后。如果Kayo没有生病,那么我们就以2为参数执行resolve函数如果Kayo生病了,那么我们用newError(Iamsad)作为参数执行reject。尽管您可以将任何要拒绝的内容作为参数传递,但建议将其传递给Error对象。
  现在,因为onMyBirthday()返回的是一个Promise,我们可以访问then、catch和finally方法。我们还可以访问早些时候在then和catch中使用传递给resolve和reject的参数。
  让我们通过如下代码来理解概念,相信通过这个例子你能了解Promise的基本概念。
  如果Kayo没有生病onMyBirthday(false)。then((result){console。log(Ihave{result}cakes);控制台打印Ihave2cakes})。catch((error){console。log(error);不执行})。finally((){console。log(Party);控制台打印Party});
  如果Kayo生病onMyBirthday(true)。then((result){console。log(Ihave{result}cakes);不执行})。catch((error){console。log(error);控制台打印我很难过})。finally((){console。log(Party);控制台打印Party});示例2:一个猜数字的游戏
  基本需求:用户可以输入任意数字系统从1到6中随机生成一个数字如果用户输入数字等于系统随机数,则给用户2分如果用户输入数字与系统随机数相差1,给用户1分,否则,给用户0分用户想玩多久就玩多久
  对于上面的需求,我们首先创建一个enterNumber函数并返回一个Promise:constenterNumber(){returnnewPromise((resolve,reject){从这开始编码});};
  我们要做的第一件事是向用户索要一个数字,并在1到6之间随机选择一个数字:constenterNumber(){returnnewPromise((resolve,reject){constuserNumberNumber(window。prompt(Enteranumber(16):));向用户索要一个数字constrandomNumberMath。floor(Math。random()61);选择一个从1到6的随机数});};
  当用户输入一个不是数字的值。这种情况下,我们调用reject函数,并抛出错误:constenterNumber(){returnnewPromise((resolve,reject){constuserNumberNumber(window。prompt(Enteranumber(16):));向用户索要一个数字constrandomNumberMath。floor(Math。random()61);选择一个从1到6的随机数if(isNaN(userNumber)){reject(newError(WrongInputType));当用户输入的值非数字,抛出异常并调用reject函数}});};
  下面,我们需要检查userNumber是否等于RanomNumber,如果相等,我们给用户2分,然后我们可以执行resolve函数来传递一个object{points:2,randomNumber}对象。
  如果userNumber与randomNumber相差1,那么我们给用户1分。否则,我们给用户0分。returnnewPromise((resolve,reject){constuserNumberNumber(window。prompt(Enteranumber(16):));向用户索要一个数字constrandomNumberMath。floor(Math。random()61);选择一个从1到6的随机数if(isNaN(userNumber)){reject(newError(WrongInputType));当用户输入的值非数字,抛出异常并调用reject函数}if(userNumberrandomNumber){如果相等,我们给用户2分resolve({points:2,randomNumber,});}elseif(userNumberrandomNumber1userNumberrandomNumber1){如果userNumber与randomNumber相差1,那么我们给用户1分resolve({points:1,randomNumber,});}else{否则用户得0分resolve({points:0,randomNumber,});}});
  下面,让我们再创建一个函数来询问用户是否想继续游戏:constcontinueGame(){returnnewPromise((resolve){if(window。confirm(Doyouwanttocontinue?)){向用户询问是否要继续游戏resolve(true);}else{resolve(false);}});};
  为了不使游戏强制结束,我们创建的Promise没有使用Reject回调。
  下面,我们创建一个函数来处理猜数字逻辑:consthandleGuess(){enterNumber()返回一个Promise对象。then((result){alert(Dice:{result。randomNumber}:yougot{result。points}points);当resolve运行时,我们得到用户得分和随机数向用户询问是否要继续游戏continueGame()。then((result){if(result){handleGuess();Ifyes,游戏继续}else{alert(Gameends);Ifno,弹出游戏结束框}});})。catch((error)alert(error));};handleGuess();执行handleGuess函数
  在这当我们调用handleGuess函数时,enterNumber()返回一个Promise对象。
  如果Promise状态为resolved,我们就调用then方法,向用户告知竞猜结果与得分,并向用户询问是否要继续游戏。
  如果Promise状态为rejected,我们将显示一条用户输入错误的信息。
  不过,这样的代码虽然能解决问题,但读起来还是有点困难。让我们后面将使用asyncawait对hanldeGuess进行重构。
  网上对于asyncawait的解释已经很多了,在这我想用一个简单概括的说法来解释:asyncawait就是可以把复杂难懂的异步代码变成类同步语法的语法糖。
  下面开始看重构后代码吧:consthandleGuessasync(){try{constresultawaitenterNumber();代替then方法,我们只需将await放在promise前,就可以直接获得结果alert(Dice:{result。randomNumber}:yougot{result。points}points);constisContinuingawaitcontinueGame();if(isContinuing){handleGuess();}else{alert(Gameends);}}catch(error){catch方法可以由try,catch函数来替代alert(error);}};
  通过在函数前使用async关键字,我们创建了一个异步函数,在函数内的使用方法较之前有如下不同:和then函数不同,我们只需将await关键字放在Promise前,就可以直接获得结果。我们可以使用try,catch语法来代替promise中的catch方法。
  下面是我们重构后的完整代码,供参考:constenterNumber(){returnnewPromise((resolve,reject){constuserNumberNumber(window。prompt(Enteranumber(16):));向用户索要一个数字constrandomNumberMath。floor(Math。random()61);系统随机选取一个16的数字if(isNaN(userNumber)){reject(newError(WrongInputType));如果用户输入非数字抛出错误}if(userNumberrandomNumber){如果用户猜数字正确,给用户2分resolve({points:2,randomNumber,});}elseif(userNumberrandomNumber1userNumberrandomNumber1){如果userNumber与randomNumber相差1,那么我们给用户1分resolve({points:1,randomNumber,});}else{不正确,得0分resolve({points:0,randomNumber,});}});};constcontinueGame(){returnnewPromise((resolve){if(window。confirm(Doyouwanttocontinue?)){向用户询问是否要继续游戏resolve(true);}else{resolve(false);}});};consthandleGuessasync(){try{constresultawaitenterNumber();await替代了then函数alert(Dice:{result。randomNumber}:yougot{result。points}points);constisContinuingawaitcontinueGame();if(isContinuing){handleGuess();}else{alert(Gameends);}}catch(error){catch方法可以由try,catch函数来替代alert(error);}};handleGuess();执行handleGuess函数示例3:从WebAPI中获取国家信息
  一般当从API中获取数据时,开发人员会精彩使用Promises。如果在新窗口打开https:restcountries。eurestv2alphacn,你会看到JSON格式的国家数据。
  通过使用FetchAPI,我们可以很轻松的获得数据,以下是代码:constfetchDataasync(){constresawaitfetch(https:restcountries。eurestv2alphacn);fetch()returnsapromise,soweneedtowaitforitconstcountryawaitres。json();resisnowonlyanHTTPresponse,soweneedtocallres。json()console。log(country);Chinasdatawillbeloggedtothedevconsole};fetchData();
  现在我们获得了所需的国家地区数据,让我们转到最后一项任务。示例4:从WebAPI中获取一个国家的周边国家列表
  下面的fetchCountry函数从示例3中的api获得国家信息,其中的参数alpha3Code是代指该国家的国家代码,以下是代码
  Task4:获得中国周边的邻国信息constfetchCountryasync(alpha3Code){try{constresawaitfetch(https:restcountries。eurestv2alpha{alpha3Code});constdataawaitres。json();returndata;}catch(error){console。log(error);}};
  下面让我们创建一个fetchCountryAndNeighbors函数,通过传递cn作为alpha3code来获取中国的信息。constfetchCountryAndNeighborsasync(){constchinaawaitfetchCountry(cn);console。log(china);};fetchCountryAndNeighbors();
  在控制台中,我们看看对象内容:
  在对象中,有一个border属性,它是中国周边邻国的alpha3codes列表。
  现在,如果我们尝试通过以下方式获取邻国信息。constneighborschina。borders。map((border)fetchCountry(border));
  neighbors是一个Promise对象的数组。
  当处理一个数组的Promise时,我们需要使用Promise。all。constfetchCountryAndNeigborsasync(){constchinaawaitfetchCountry(cn);constneighborsawaitPromise。all(china。borders。map((border)fetchCountry(border)));console。log(neighbors);};fetchCountryAndNeigbors();
  在控制台中,我们应该能够看到国家地区对象列表。
  以下是示例4的所有代码,供您参考:constfetchCountryasync(alpha3Code){try{constresawaitfetch(https:restcountries。eurestv2alpha{alpha3Code});constdataawaitres。json();returndata;}catch(error){console。log(error);}};constfetchCountryAndNeigborsasync(){constchinaawaitfetchCountry(cn);constneighborsawaitPromise。all(china。borders。map((border)fetchCountry(border)));console。log(neighbors);};fetchCountryAndNeigbors();总结
  完成这4个示例后,你可以看到Promise在处理异步操作或不是同时发生的事情时很有用。相信在不断的实践中,对它的理解会越深、越强,希望这篇文章能对大家理解Promise和AsyncAwait带来一些帮助。
  这是本文中使用的代码:Asdkjbasrksbr。

家和万事惊曝光全新剧照吴镇宇袁咏仪再演夫妻默契十足星关系1月8日讯由著名导演邱礼涛执导,吴镇宇、古天乐、袁咏仪、张达明领衔主演,吴肇轩、蔡颂思、林雪、林子聪、李璨琛、孔令令等演员倾力出演的国民荒诞喜剧《家和万事惊》已正式宣布定……陈坤2019行走的力量分享展开幕探路者装备一路护航很多人对明星的印象都是在影视剧、MV、发布会,很多明星也非常热心公益事业,心灵建设公益项目行走的力量2019年度分享展于12月16日在北京山下剧场正式开幕,一个充满乐趣又不失深……悬疑电影22年后的自白预售开启开年力作映照社会现实星关系1月8日讯1月11日,犯罪悬疑电影《22年后的自白》将在全国各大院线惊彩上映,这部2019开年悬疑大作在定档伊始便备受瞩目,该片在日本上映时成绩斐然,获得年度票房前十的优……高通确认参加2021年进博会孟樸5G市场成长空间十分巨大在第三届中国国际进口博览会会场,无处不在的5G网络覆盖,为全球前沿的5G应用打造了亮眼的平台。从第一届时5G初露头角,到第三届时5G产品遍布展区、大放异彩,进博会见证了全球5G……包贝尔亮相大人物首映礼首演反派寻求角色突破(高清组图)星关系1月7日讯昨日,由五百导演执导,王千源、包贝尔、王迅主演的犯罪动作电影《大人物》于北京举行首映礼发布会,映后主创们就电影观后感与现场观众分享台前幕后故事。不少观众表示包贝……法拉利女司机追尾后扬言砸死对方,交警开豪车不代表有特权徽州宴事件刚刚平息不久,广州市一位法拉利488驾驶员冯某因语言粗鄙、辱骂被追尾马自达司机陈某再次引起了大家对土豪们的关注。据消息显示,2021年8月13日,位于广州市龙口……家和万事惊海报预告双发吴镇宇袁咏仪遭现实狂虐星关系1月7日讯由著名导演邱礼涛执导,吴镇宇、古天乐、袁咏仪、张达明领衔主演,吴肇轩、蔡颂思、林雪、林子聪、李璨琛、孔令令等演员倾力出演的国民荒诞喜剧《家和万事惊》今日发布易燃……彼得大帝揭秘掠食城市未来世界城市之间上演弱肉强食生死战星关系1月7日讯由执导过《指环王》《霍比特人》系列的著名导演彼得杰克逊打造的全新科幻史诗巨制《掠食城市》今日发布未来世界版预告,彼得杰克逊惊喜亮相化身讲解员,为观众介绍未来世界……白蛇缘起首轮点映获赞本周二起限时点映正式开启星关系1月7日讯由追光动画、华纳兄弟联合出品,即将于2019年1月11日全国开画的东方爱情魔幻电影《白蛇:缘起》在上周末开启了全国31城300场点映,周末两天惊人的上座率也证明……实用一个高性能通信库的简单使用分享前言最近的工作中也有用到nanomsg,本篇推文来简单分享一下nanomsg的基本使用。nanomsg简介nanomsg是一个实现了几种可扩展协议的高性能通信库;可……廉政风云预告海报双发刘青云张家辉上演打虎行动反腐到底星关系1月7日讯打虎行动哪家强?这个春节看麦庄!由麦兆辉执导,庄文强、黄斌担任监制,刘青云、张家辉、林嘉欣、方中信、袁咏仪主演的春节档反腐电影《廉政风云》,今日曝光打虎行动版预……白蛇缘起首映大获成功300场点映今日全国进行中星关系1月7日讯由追光动画、华纳兄弟联合出品的东方爱情魔幻电影《白蛇:缘起》将于1月11日正式上映。今日片方再度曝光几张全新精美剧照,阿宣和小白这对恋人的更多爱情画面曝光,人妖……
手机市场下半年必迎涨价潮?高通中国区董事长孟璞:缺芯这个局面还将持续一段时间5月21日,高通举办了2021高通技术与合作峰会。在这个峰会上,高通中国区董事长孟璞不但向大家描绘了未来的愿景,也针对缺……江苏车主提了台比亚迪宋PLUS新能源,驾驶4200公里,有许江苏车主提了台比亚迪宋PLUS新能源,驾驶4200公里后,有许多话要说。我是江苏车主,提的是2021款DMi110KM旗舰型,裸车价格为15。88万元,目前已经行驶了42……超级推荐大改版,阿里妈妈引力魔方上线大家心心念念的超级推荐大改版终于来了!最近,阿里妈妈核心产品【超级推荐】进行了重大产品升级,升级为【阿里妈妈引力魔方】。新产品在原有强大信息流资源下,引入了手淘首页……realmeFlash,安卓首款磁吸无线充电手机本期内容应前几期粉丝留言投稿,所以小编带各位小伙伴来了解一下这款安卓首款磁吸无线充电手机!真我Flash这款手机性能方面,可能搭载了高通骁龙888plusLPDDR5UF……华为放大招了或将启用D系列旗舰机型,D10系列强势归来朋友们,大家好!欢迎您点开笑呵呵的小丑的文章,您的每一次浏览都是对小编最大的鼓励!事不宜迟,咱们进入本篇的正题。说到华为,不得不说它在今年的表现可谓是一波未平又起一波。首……红米们感受下OPPO子品牌Realme杀回国内针对不同市场推出子品牌俨然已经成了手机厂商们的通用套路,尤其是蓝绿大厂OV近期动作频频。这边厢,vivo高调打造了iQOO;那边厢,OPPO运作已久的Realme也亮出了獠牙。……快人一步我是专业的!罗技无线蓝牙键鼠打造移动办公黑科技一、写在前面大家好,我是你们的oak酱!和大多数商务工作者一样,我需要经常坐在电脑前,回家之后我也常加班,另外,我会趁着周末码字分享生活好物给大家讲真,键鼠使……焕新升级为智趣而来17。48万1TA系列上市新四化浪潮席卷之下,新能源汽车正在重构人们对于未来出行的想象。9月26日,广汽本田2022款VE1TA系列上市发布会召开。作为广汽本田首款纯电SUV,VE1开启了广汽本田电动化……域乎春节抽奖活动,赢取iPhone12等大礼新年快乐Happynewyear为回馈广大用户对域乎鲸矿的信任和鼓励,特推出春节抽奖活动,活动时间是2021年2月8日09:002021年2月14日20:00……AppStore限免通讯录备份和导出多合一照片等,共5款在今天限免的iOS限免应用中,波老师精选了以下5款限免应用。复制logo上方名字即可前往AppStore下载。如遇恢复原价,则表示限免已结束,请谨慎下载。具体下载方式:复……拿铁是VV6中期改款?续航高达1000Km,满满科技感你心动长城集团这些年来旗下的矩阵品牌都散发着各自的魅力,哈弗以亲民且实用一直受消费者爱戴;坦克则是新晋网红,凭借硬派气息保持着超高的热度;欧拉则抓住了女性的心理,迅速走红;魏牌则是最……WiFi相机FCC认证办理WiFi相机FCC认证办理步骤介绍。Wifi数码相机即相机带wifi功能,可以与wifi连接,让能通过网络更加便捷的上传或分享照片。但一般这类产品要出口美国则必须要办理FCC认……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网