因而,在本文中,她们将找出一类方式,透过仅采用需用的国际标准特性和方式来确认允诺的现阶段状况,这种她们的标识符就能保证在任何人地方性都能恒定组织工作。
允诺的可能将状况是甚么?
Promise 能处在四种状况:
Pending,当它仍未导出为值或因严重错误而被婉拒时Fulfilled,当她们化解了两个值Rejected, 当她们婉拒了已确认的允诺被称作“ unsettled”,罢了履行职责和婉拒的允诺被称作“已化解”。
她们能很难地看到大部份四种状况,只需极少的标识符:
const a = new Promise((resolve,reject) => { /* nothing */ }); // Promise {<pending>} constb =Promise.resolve(22); // Promise {<fulfilled>: 22} const c = Promise.reject(“bad”); // Promise {<rejected>: bad}很明显,promises 在内部以某种方式跟踪它的状况,但是没有她们能访问它的可见的公共特性。如果她们尝试Object.keys(somePromise),她们会得到两个空数组。
所以,如果她们想获得允诺的状况,她们需要找出一些方式来采用需用的函数;没有她们能采用的“后门”。幸运的是,有一类方式能实现这一点,她们将在接下来看见。
实施她们的方式
以她们之前的Waiting For Some Promises为例?在责任编辑中,她们将定义两个独立的函数并修改Promise.prototype以简化获得所需状况的过程。
Promise.prototype.status = function () { return promiseStatus(this); };async函数。如何?她们能Promise.race()为此采用。
当您调用Promise.race()一系列允诺时,它会在任何人允诺得到化解后立即化解。考虑到这一点,她们能称之为提供两个允诺:两个是她们关心的,另两个是已经确认的。这将如何组织工作?
如果Promise.race()导出为她们已经确认的允诺返回的值,则另两个未决。如果Promise.race()导出为其他任何人内容,则它要么具有值(因而,允诺已实现),要么由于某种原因导致严重错误(允诺被婉拒。)所以,她们能这种写:
const promiseStatus = async (p) => { const SPECIAL = Symbol(“status”); return Promise.race([p, Promise.resolve(SPECIAL)]).then((value) => (value === SPECIAL ? “pending” : “fulfilled”), (reason) => “rejected”); };(给眼尖的 JavaScript 开发者的提示:她们真的不需要async在第一行指定;根据定义,返回 promise 的函数已经是async.)
这是如何运作的?她们必须保证她们已经确认的允诺导出为其他标识符无法导出的值。采用 asymbol是关键;符号保证是唯一的。
因而,如果Promise.race()导出为某个值,如果它是她们的符号,则意味着她们要测试的允诺仍然悬而未决。否则,如果比赛化解为任何人其他价值,则其他允诺得到履行职责。另一方面,如果比赛以婉拒结束,她们能肯定地知道被测试的允诺被婉拒了。(您可能将想查看.then()组织工作原理。)
她们做到了!她们的promiseStatus()方式是一个async,但是马上就化解了。让她们看看如何测试它!
测试她们的方式
首先,她们需要一些虚拟的允诺,她们能重用她们在等待一些允诺?文章。
const success = (time, value) => new Promise((resolve) => setTimeout(resolve, time, value)); const failure = (time, reason) => newPromise((_, reject) => setTimeout(reject, time, reason));该success()函数返回两个允诺,该允诺将在一段时间后导出为两个值,该failure()函数返回一个允诺,该允诺将在一段时间后以某种原因婉拒。现在她们能编写以下测试,如果她们愿意,能将其转换为Jest单元测试。
const ppp = success(200, 33); constqqq = failure(500, “Why not?”); promiseStatus(ppp).then(console.log); // pending promiseStatus(qqq).then(console.log); // pending ppp.then(() => { promiseStatus(ppp).then(console.log); // fulfilledpromiseStatus(qqq).then(console.log); // pending }); qqq.catch(() => { promiseStatus(ppp).then(console.log);// fulfilled promiseStatus(qqq).then(console.log); // rejected });让她们分析一下结果。前两个测试产生“已确认”结果,因为还没有时间来化解任何人允诺。如果她们等到ppp化解了,它的状况就会变成“已完成”,但qqq仍然是“已确认”。如果她们然后等到qqqsettled,ppp仍然是“fulfilled”(那里没有变化)但现在qqq是“rejected”——完全正确!
输入她们的方式
她们必须从她们的promiseStatus()功能开始。PromiseStatus她们能用四种可能将的结果定义两个辅助类型。她们的promiseStatus()函数将 aPromise<any>作为参数并返回Promise<PromiseStatus>结果。
type PromiseStatus = “pending” | “fulfilled” | “rejected”; const promiseStatus = (p: Promise<any>): Promise<PromiseStatus> => { const SPECIAL = Symbol(“status”); return Promise.race([p, Promise.resolve(SPECIAL)]).then( (value) => (value === SPECIAL ? “pending” : “fulfilled”), (reason) => “rejected” ); };要修改Promise.prototype,她们必须添加两个全局定义,如下所示。
declare global { interface Promise<T> { status(): Promise<PromiseStatus>; } }有了这个定义,她们现在能将她们的函数添加到Promise.prototype.
Promise.prototype.status = function () { return promiseStatus(this); };这种,她们就能直接采用 status 方式,如下所示:
ppp.status().then(console.log);或者
const rrr = await qqq.status(); if (rrr === …) { … }她们完成了!
结论
在责任编辑中,她们化解了了解允诺状