电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

JS異步代碼單元測試之神奇的Promise

瀏覽:103日期:2024-03-27 15:02:46
前言

寫這篇文章的起因是在寫單元測試時,做形如下測試時

new Promise((resolve, reject) => reject(1)).then().catch(err => { console.log(err)})async function jestTest () { await Promise.resolve().then() console.log(’這個時候catch預期已經被調用,且輸出日志’)}jestTest()

無法使用await將測試代碼恰好阻塞到catch在Event Loop中被調用后的時機,從而檢測到catch的執(zhí)行,通過測試。

而使用“神奇”一詞則是因為 promsie 的鏈式調用中確實有很多默認的 handler 和值的隱含傳遞。

promise 的鏈式調用

為了不浪費大家的時間,我們先看一個例子:

Promise.resolve(’promise1’).then(res => { console.log(’promise1-1 then’)}).then(res => { console.log(’promise1-2 then’)}).then(res => { console.log(’promise1-3 then’)}).then(res => { console.log(’promise1-4 then’)})Promise.resolve(’promise2’).then(res => { console.log(’promise2-1 then’) throw new Error(’mock error 1’)}).then(res => { console.log(’promise2-2 then’) throw new Error(’mock error 2’)}).catch(err => { console.log(err)})

如果你答出的上述代碼的輸出順序與下述相同,那么你可以跳過這篇文章:

promise1-1 then

promise2-1 then

promise1-2 then

promise1-3 then

Error: mock error 1

promise1-4 then

首先有一個前提,就是你已經知道了,這兩個 promise 的 then 的調用是交叉入棧的(從頭三行輸出也能看出來),如果不清楚這部分內容,可以查閱 Event Loop 的相關文章,同時需要注意的是,在文章所指明的版本中 Chrome 與 NodejsEvent Loop 機制已經相同。

MDN 的錯誤

我們去翻閱下原本(我做了修改) MDN 關于 catch 的一段描述:

Basically, a promise chain stops if there’s an exception, looking down the chain for catch handlers instead.

鏈式調用在發(fā)生異常時會停止,在鏈上查找 catch 語句來執(zhí)行。

我最初的誤解與此相同,誤以為 catch 會直接抓到第一個throw Error,即Error會在promise1-2之后輸出,即promise2-2所在的then并不會被加入調用棧。

而通過觀察實際的輸出結果發(fā)現(xiàn)并非如此,那么可以說明 MDN 解釋的字面意思應該是錯的,鏈式調用并沒有停止,而是執(zhí)行了我們沒看到的東西。

鏈式的默認處理

這時我們需要知道then的一個默認處理,同樣直接引用 MDN 的描述:

If the Promise that then is called on adopts a state (fulfillment or rejection) for which then has no handler, a new Promise is created with no additional handlers, simply adopting the final state of the original Promise on which then was called.

如果你的 promise 的 then 缺少了對應狀態(tài)處理的回調,那么 then 會自動生成一個接受此 promise 狀態(tài)的 promise,即 then 會返回一個狀態(tài)引用相同的 promsie,交給后續(xù)的調用。

那么上述代碼中的第二個 promise 部分就等效于

Promise.resolve(’promise2’).then(res => { console.log(’promise2-1 then’) throw new Error(’mock error 1’)}).then(res => { console.log(’promise2-2 then’) throw new Error(’mock error 2’)// 注意這個 onRejected}, (err) => { return Promise.reject(err)}).catch(err => { console.log(err)})

也就是說在輸出結果的promise1-2和promise1-3之間是執(zhí)行了promise2-2所在的then的,也就是說鏈式調用并沒有直接停止,promise2-2所在的then還是被加入了調用棧。而catch并不是直接catch的第一個then拋出的錯誤,而是這個隱藏的onRejected返回的同樣狀態(tài)的promise。

簡寫

同理我們需要知道的是,catch(onRejected)是then(undefined, onRejected)的簡寫,即就算調用鏈的前置調用沒有發(fā)生錯誤,catch也是會進入調用棧而非直接跳過的。

Promise.resolve(’promise1’).then(res => { console.log(’promise1-1 then’)}).then(res => { console.log(’promise1-2 then’)}).then(res => { console.log(’promise1-3 then’)})Promise.resolve(’promise2’).then(res => { console.log(’promise2-1 then’)}).catch(err => { console.log(err)}).then(res => { console.log(’其實我是 promise2-3 then’)})async await

首先需要注意的是在文章指明的 NodeJs 和 Chrome 版本中,f(await promise)完全等同于promise.then(f)。

當然,討論promise的時候,我們也不能拋開async await。雖然兩者在 promise 狀態(tài)為 onResolve 時處理邏輯相同,但錯誤處理的執(zhí)行邏輯并不一樣,在async await中發(fā)生錯誤時,才是真正的直接跳過后續(xù)await的執(zhí)行

const promiseReject = new Promise((resolve, reject) => { reject(new Error(’錯誤’))})const promiseResolve1 = new Promise((resolve, reject) => { resolve(’正確’)})const promiseResolve2 = new Promise((resolve, reject) => { resolve(’正確’)})const promiseResolve3 = new Promise((resolve, reject) => { resolve(’正確’)})function demo1 () { promiseReject .then(() => {console.log(’1-1’) }) .catch(err => {console.log(’1-2’) })}async function demo2 () { try {await promiseRejectawait promiseResolve1await promiseResolve2await promiseResolve3 } catch (error) {console.log(’2-1’) }}// 2-1// 1-2

以上就是JS異步代碼單元測試之神奇的Promise的詳細內容,更多關于JS異步代碼之Promise的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 济南菜鸟驿站广告|青岛快递车车体|社区媒体-抖音|墙体广告-山东揽胜广告传媒有限公司 | 硫化罐-胶管硫化罐-山东鑫泰鑫智能装备有限公司 | 天津电机维修|水泵维修-天津晟佳机电设备有限公司 | 山东活动策划|济南活动公司|济南公关活动策划-济南锐嘉广告有限公司 | 活性氧化铝球|氧化铝干燥剂|分子筛干燥剂|氢氧化铝粉-淄博同心材料有限公司 | 全钢实验台,实验室工作台厂家-无锡市辰之航装饰材料有限公司 | 面粉仓_储酒罐_不锈钢储酒罐厂家-泰安鑫佳机械制造有限公司 | 立式硫化罐-劳保用品硫化罐-厂家直销-山东鑫泰鑫硫化罐厂家 | 塑料造粒机「厂家直销」-莱州鑫瑞迪机械有限公司 | 高柔性拖链电缆_卷筒电缆_耐磨耐折聚氨酯电缆-玖泰特种电缆 | 流量检测仪-气密性检测装置-密封性试验仪-东莞市奥图自动化科技有限公司 | 铁盒_铁罐_马口铁盒_马口铁罐_铁盒生产厂家-广州博新制罐 | 网络推广公司_网络营销方案策划_企业网络推广外包平台-上海澜推网络 | 科昊仪器超纯水机系统-可成气相液氮罐-美菱超低温冰箱-西安昊兴生物科技有限公司 | 刺绳_刀片刺网_刺丝滚笼_不锈钢刺绳生产厂家_安平县浩荣金属丝网制品有限公司-安平县浩荣金属丝网制品有限公司 | 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | 板框压滤机-隔膜压滤机-厢式压滤机生产厂家-禹州市君工机械设备有限公司 | 氨水-液氨-工业氨水-氨水生产厂家-辽宁顺程化工 | 超高频感应加热设备_高频感应电源厂家_CCD视觉检测设备_振动盘视觉检测设备_深圳雨滴科技-深圳市雨滴科技有限公司 | 硫酸钡厂家_高光沉淀硫酸钡价格-河南钡丰化工有限公司 | 冷热冲击试验箱_温度冲击试验箱价格_冷热冲击箱排名_林频厂家 | 知企服务-企业综合服务(ZiKeys.com)-品优低价、种类齐全、过程管理透明、速度快捷高效、放心服务,知企专家! | 上海办公室装修公司_办公室设计_直营办公装修-羚志悦装 | 胶原检测试剂盒,弹性蛋白检测试剂盒,类克ELISA试剂盒,阿达木单抗ELISA试剂盒-北京群晓科苑生物技术有限公司 | 涂层测厚仪_光泽度仪_uv能量计_紫外辐照计_太阳膜测试仪_透光率仪-林上科技 | 涿州网站建设_网站设计_网站制作_做网站_固安良言多米网络公司 | 游动电流仪-流通式浊度分析仪-杰普仪器(上海)有限公司 | 聚合氯化铝价格_聚合氯化铝厂家_pac絮凝剂-唐达净水官网 | 丹佛斯压力传感器,WISE温度传感器,WISE压力开关,丹佛斯温度开关-上海力笙工业设备有限公司 | 香蕉筛|直线|等厚|弧形|振动筛|香蕉筛厂家-洛阳隆中重工 | 破碎机_上海破碎机_破碎机设备_破碎机厂家-上海山卓重工机械有限公司 | 真空冷冻干燥机_国产冻干机_冷冻干燥机_北京四环冻干 | 厌氧工作站-通用型厌氧工作站-上海胜秋科学仪器有限公司 | 冷凝锅炉_燃气锅炉_工业燃气锅炉改造厂家-北京科诺锅炉 | 除湿机|工业除湿机|抽湿器|大型地下室车间仓库吊顶防爆除湿机|抽湿烘干房|新风除湿机|调温/降温除湿机|恒温恒湿机|加湿机-杭州川田电器有限公司 | 翰墨AI智能写作助手官网_人工智能问答在线AI写作免费一键生成 | 除湿机|工业除湿机|抽湿器|大型地下室车间仓库吊顶防爆除湿机|抽湿烘干房|新风除湿机|调温/降温除湿机|恒温恒湿机|加湿机-杭州川田电器有限公司 | 四川成人高考_四川成考报名网 | 闭端端子|弹簧螺式接线头|防水接线头|插线式接线头|端子台|电源线扣+护线套|印刷电路板型端子台|金笔电子代理商-上海拓胜电气有限公司 | 通辽信息港 - 免费发布房产、招聘、求职、二手、商铺等信息 www.tlxxg.net | 江苏全风,高压风机,全风环保风机,全风环形高压风机,防爆高压风机厂家-江苏全风环保科技有限公司(官网) |