远洋国际一期官方网站建设外网下载

张小明 2026/1/7 18:01:15
远洋国际一期官方网站建设,外网下载,如何做优化网站的原创性文章,网站界面设计需要前言之前找工作的时候凭感觉做了一个实现 Promise A 规范的 Promise的练习#xff0c;最近在准备新的工作机会#xff0c;又看到了这个面试题。我感觉之前的实现有很大优化空间。之前用前次调用结果作为标记来实现 Promise 多次 resolve 和 reject 触发的正确逻辑#xff0c…前言之前找工作的时候凭感觉做了一个实现 Promise A 规范的 Promise的练习最近在准备新的工作机会又看到了这个面试题。我感觉之前的实现有很大优化空间。之前用前次调用结果作为标记来实现 Promise 多次 resolve 和 reject 触发的正确逻辑感觉有点太麻烦了通过和 AI 的深入交流这完全可以用简单的布尔值标记做到。这篇博客权当是复习吧...简介 Promise A 规范变量和术语Promise 表示异步操作的最终结果。Promise 具有 3 种状态pending等待中、fulfilled成功执行、rejected失败拒绝初始状态为 pending切换为 fulfilled 或者 rejected 后就不能再转换。处于非 pending 状态时称为 settled。const testPromise new Promise((resolve, reject) {// DO SOMETHING})像这样子传入的函数我们称为executorresolve和reject会触发 Promise 的状态改变以及数据更新。value表示成功执行fulfilled 状态的 Promise 的结果reason表示失败拒绝rejected 状态的 Promise 的原因它们可以取 JS 中任何合法的值。Promise A 规范的 Promise 上的方法只有简单的thencatch、finally之类的方法并不包含。settlednot settled调用resolve(value)settlednot settled抛出异常调用reject(reason)当前未执行resolve和reject没有抛出异常创建Promise执行executor(resolve, reject)executor执行结果?Promise settled?忽略重复调用状态: pending → rejected存储reasonPromise settled?状态: pending → fulfilled存储valuependingthen 方法then方法具有onFulfilled和onRejected两个入参返回一个 Promise链式调用。举个栗子const temp testPromise.then(function onFulfilled (value) {// DO SOMETHING}, function onRejected (reason) {// DO SOMETHING})console.log(temp instanceof Promise) // trueconsole.log(temp testPromise) // falsePromise 从 pending 状态切换到 fulfilled 或者 rejected 时执行此前then传入的onFulfilled或onRejected。fulfilled 状态的 Promise 会执行then传入的onFulfilledrejected 状态的 Promise 会执行then传入的onRejected。执行onFulfilled或onRejected的结果会被传入新的 Promise temp的resolve方法中如果发生了错误则传入reject中改变的状态和数据。onFulfilled或者onRejected不是函数时返回的 Promise 与原 Promise 具有相同的状态和数据传值穿透。用一个流程图总结一下pendingfulfilledrejected正常返回正常返回抛出异常抛出异常状态变为fulfilled状态变为rejected调用promise.then(onFulfilled, onRejected)当前状态?注册回调到队列等待状态改变异步执行onFulfilled(value)异步执行onRejected(reason)onFulfilled返回值?onRejected返回值?Promise Resolution Procedure调用新Promise的reject状态: rejected返回新PromisePromise Resolution Procedureresolve被触发时发生什么事了此时 Promise 的状态仍未真正变化会进入一段处理程序规范称之为 Promise Resolution Procedure主要逻辑是如果传入的是非 thenable 对象或者基本类型则直接修改 Promise 的状态和数据是 thenable 就执行下面 thenable 相关逻辑。此外不支持我返回我自己onFulfilled或者onRejected返回该then返回的 Promise 时抛出TypeError错误例如const temp testPromise.then(function onFulfilled (value) {return temp})处理 thenable 对象thenable 的对象是具有then方法的对象或者函数。then方法接受两个回调函数onResolvePromise和onRejectPromise类似于这里的 Promise 的then。thenable 实际上包括实现了 Promise A 规范的 Promise例如 ES6 原生的 Promise。举个 thenable 对象的栗子const thenable {then: function (onResolvePromise, onRejectPromise) {onResolvePromise(miao~~)}}如果触发了onFulfilled返回了一个 thenable。如果是该 Promise 的实例不是当前 Promise则传入当前 Promise 的resolve和reject调用then方法。兼容其他 thenable调用then方法传入当前 Promise 的resolve和reject像该 Promise 实例一样解析。允许其他 thenable 对象乱写这里需要处理 thenable 对象重复触发onResolvePromise或/和onRejectPromise的情况这两个回调函数最多只能改变 1 次 Promise 的状态。其他详细见 Promise A 规范。这里再用个流程图总结一下是是否否调用resolvePromise(x)调用rejectPromise(reason)抛出异常not settlednot settledsettledsettledPromise Resolution Procedure返回值是thenable?是否返回自身?抛出TypeError调用thenable.then(resolvePromise, rejectPromise)调用新Promise的resolve状态: fulfilledthenable行为?Promise settled?Promise settled?调用新Promise的reject状态: rejected状态: fulfilledvalue x状态: rejectedreason reason忽略重复调用返回新Promise返回rejected Promisereason TypeError前期准备先定义好类型和一个发起微任务的辅助函数。enum PromiseState {fulfilled fulfilled,pending pending,rejected rejected}type ExecutorT (resolve: (value: T | PromiseLikeT) void,reject: (reason?: any) void) voidconst scheduleMicrotask (callback: () void) {if (typeof queueMicrotask function) {queueMicrotask(callback)} else if (typeof process ! undefined process.nextTick) {process.nextTick(callback)} else {Promise.resolve().then(callback)}}简单地写一个 Promiseclass ShikaPromiseT any {private state: PromiseState PromiseState.pendingprivate value: T | undefinedprivate reason: anyconstructor(executor: ExecutorT) {try {executor((value) this.resolve(value),(reason) this.reject(reason))} catch (error) {this.reject(error)}}private resolve(value: T): void {// 不支持 resolve 自己if (value this) {this.reject(new TypeError(Cannot resolve promise with itself))return}scheduleMicrotask(() {this.state PromiseState.fulfilledthis.value value})}private reject(reason: any): void {scheduleMicrotask(() {this.state PromiseState.rejectedthis.reason reason})}thenTResult1 T, TResult2 never(onFulfilled?: ((value: T) TResult1 | PromiseLikeTResult1) | null | undefined,onRejected?: ((reason: any) TResult2 | PromiseLikeTResult2) | null | undefined) {// TODO}}下面就来写then方法实现异步的链式调用。then 方法then返回一个 Promise虽然 Promise A 规范没有说明需要返回的 Promise 不能和原有的是同一个但是考虑到后续链式调用也会涉及到 Promise 状态的改变所以这里就返回一个新的 Promise。fulfilled 和 rejected 状态假设const promise2 promise1.then(onFulfilled, onRejected)调用promise1.then时创建一个新的 Promise promise2返回出去。用过 ES6 的Promise很好理解如果原有promise1是 fulfilled 的则在新的promise2的executor中的resolve传入onFulfilled的结果如果promise1处于失败状态rejected 了则在promise2的resolve中传入onRejected的结果。举个栗子const promiseTmp1 Promise.resolve(ok).then(value value, reason reason)// 此时 promiseTmp1.value 是 okconst promiseTmp2 Promise.resolve(error).then(value value, reason reason)// 此时 promiseTmp2.value 是 error下面编写 fulfilled 和 rejected 状态的处理逻辑。// ...class ShikaPromise {// ...thenTResult1 T, TResult2 never(onFulfilled?: ((value: T) TResult1 | PromiseLikeTResult1) | null | undefined,onRejected?: ((reason: any) TResult2 | PromiseLikeTResult2) | null | undefined): ShikaPromiseTResult1 | TResult2 {return new ShikaPromiseTResult1 | TResult2((resolve, reject) {const handleCallback (isFulfilled: boolean) {scheduleMicrotask(() {const callback isFulfilled ? onFulfilled : onRejectedconst data isFulfilled ? this.value : this.reason// 传值穿透if (typeof callback ! function) {if (isFulfilled) {resolve(data as TResult1)} else {reject(data)}return}try {const result callback(data)resolve(result)} catch (error) {reject(error)}})}switch (this.state) {case PromiseState.fulfilled:handleCallback(true)breakcase PromiseState.rejected:handleCallback(false)breakdefault:// TODO}})}}pending 状态promise1在等待的时候可以在promise1上新建两个属性fulfilledHandlers、rejectedHandlers缓存给promise2触发resolve和reject的回调函数。promise2处于 pending 状态promise1切换状态后触发这些回调函数用来改变promise2的状态。// ...class ShikaPromise {// ...// 记录等待 fulfilled 或者 rejected 后执行的回调函数private fulfilledHandlers: Array() void []private rejectedHandlers: Array() void []// ...private resolve(value: T): void {scheduleMicrotask(() {this.state PromiseState.fulfilledthis.value valueconst handlers this.fulfilledHandlers.splice(0)handlers.forEach((h) h())})}private reject(reason: any): void {scheduleMicrotask(() {this.state PromiseState.rejectedthis.reason reasonconst handlers this.rejectedHandlers.splice(0)handlers.forEach((h) h())})}// ...then (onFulfilled?: ThenCallback, onRejected?: ThenCallback) {return new ShikaPromiseTResult1 | TResult2((resolve, reject) {// ...switch (this.state) {// ...default:this.fulfilledHandlers.push(() handleCallback(true))this.rejectedHandlers.push(() handleCallback(false))}})}}防止多次触发我们通过添加标记isResolved记录是否已经触发resolve。当重复触发resolve和reject时遇到isResolved为true就返回。// ...class ShikaPromiseT any {// ...private isResolved false// ...private resolve(value: T | PromiseLikeT): void {if (this.isResolved) returnif (value this) {this.reject(new TypeError(Cannot resolve promise with itself))return}// TODO: thenable 处理this.fulfill(value as T)}private fulfill(value: T): void {if (this.isResolved) returnthis.isResolved truescheduleMicrotask(() {this.state PromiseState.fulfilledthis.value valueconst handlers this.fulfilledHandlers.splice(0)handlers.forEach((h) h())})}private reject(reason: any): void {if (this.isResolved) returnthis.isResolved true// ...}// ...}解析 thenable 对象如果遇到 thenable 对象等待其进入 fulfilled 或者 rejected 状态同样的thenable 对象也需要防止重复进入 fulfilled 和 rejected 状态。class ShikaPromiseT any {// ...private resolve(value: T | PromiseLikeT): void {// ...const thenable this.getThenable(value)if (thenable) {this.resolveThenable(thenable)} else {this.fulfill(value as T)}}private getThenable(value: any): { then: Function; target: any } | null {if (value ! null (typeof value object || typeof value function)) {try {// 在规范中有 Let then be x.then 的描述测试用例中 value.then 只能被取一次const then value.thenif (typeof then function) {return { then, target: value }}} catch (error) {this.reject(error)}}return null}private resolveThenable(thenable: { then: Function; target: any }): void {let called falsetry {thenable.then.call(thenable.target,(value: any) {if (called) returncalled truethis.resolvevaluey)},(reason: any) {if (called) returncalled truethis.reject(reason)})} catch (error) {if (!called) this.reject(error)}}}其他方法JS 的 Promise下面就来实现一下 JS 的 Promse 的catch和finally。catch就是then方法只提供第二个参数。finally方法回调函数不接收任何参数返回一个状态和数据与原来相同的 Promise。class ShikaPromise {catchTResult never(onRejected?: ((reason: any) TResult | PromiseLikeTResult) | null | undefined): ShikaPromiseT | TResult {return this.then(null, onRejected)}finally(onFinally?: (() void) | null | undefined): ShikaPromiseT {return this.then((value) {onFinally?.()return value},(reason) {onFinally?.()throw reason})}}还有Promise.resolve和Promise.reject两个静态方法class ShikaPromise {static resolveT(value: T | PromiseLikeT): ShikaPromiseT {return value instanceof ShikaPromise ? value : new ShikaPromise((resolve) resolve(value))}static rejectT never(reason?: any): ShikaPromiseT {return new ShikaPromise((_, reject) reject(reason))}}如果 Promise 可以停止如果想要 Promise 后面的thencatch、finally都不会触发这里只需要返回一个 pending 状态的 Promise。这里实现一个时链式调用停止的cancel方法和返回 pending 的 Promise 的wait方法class ShikaPromise {static wait(): ShikaPromisenever {return new ShikaPromise(() {})}cancel(): ShikaPromisenever {return new ShikaPromise(() {})}}Promise A 测试下载 promises-aplus-tests 包npm i promises-aplus-tests要求 Promise 所在文件采用 commonjs 方式导出。还需要在 Promise 上实现静态方法class ShikaPromise {static deferredT() {let resolve!: (value: T | PromiseLikeT) voidlet reject!: (reason?: any) voidconst promise new ShikaPromiseT((res, rej) {resolve resreject rej})return { promise, resolve, reject }}}promises-aplus-tests Promise 的所在文件即可运行如果你在用 TS文件为编译后的文件例如promises-aplus-tests dist/文件名.jsPromise A 的测试用例覆盖面非常全调试时烦死了x通过了所有 817 条用例就说明你的 Promise 实现了 Promise A 标准了。我把 TS 编译和运行测试用例在 package.json 组装成一条命令{// ...scripts: {// ...test: tsc promises-aplus-tests dist/文件名.js,},// ...}这里 tsc 会默认编译 tsconfig.json 设置的根目录这里是 ./src然后放到输出目录中这里是 ./dist。最终实现enum PromiseState {fulfilled fulfilled,pending pending,rejected rejected}type ExecutorT (resolve: (value: T | PromiseLikeT) void,reject: (reason?: any) void) voidconst scheduleMicrotask (callback: () void) {if (typeof queueMicrotask function) {queueMicrotask(callback)} else if (typeof process ! undefined process.nextTick) {process.nextTick(callback)} else {Promise.resolve().then(callback)}}class ShikaPromiseT any {private state: PromiseState PromiseState.pendingprivate value: T | undefinedprivate reason: anyprivate fulfilledHandlers: Array() void []private rejectedHandlers: Array() void []private isResolved falseconstructor(executor: ExecutorT) {try {executor((value) this.resolve(value),(reason) this.reject(reason))} catch (error) {this.reject(error)}}private resolve(value: T | PromiseLikeT): void {if (this.isResolved) returnif (value this) {this.reject(new TypeError(Cannot resolve promise with itself))return}const thenable this.getThenable(value)if (thenable) {this.resolveThenable(thenable)} else {this.fulfill(value as T)}}private fulfill(value: T): void {if (this.isResolved) returnthis.isResolved truescheduleMicrotask(() {this.state PromiseState.fulfilledthis.value valueconst handlers this.fulfilledHandlers.splice(0)handlers.forEach((h) h())})}private reject(reason: any): void {if (this.isResolved) returnthis.isResolved truescheduleMicrotask(() {this.state PromiseState.rejectedthis.reason reasonconst handlers this.rejectedHandlers.splice(0)handlers.forEach((h) h())})}private getThenable(value: any): { then: Function; target: any } | null {if (value ! null (typeof value object || typeof value function)) {try {const then value.thenif (typeof then function) {return { then, target: value }}} catch (error) {this.reject(error)}}return null}private resolveThenable(thenable: { then: Function; target: any }): void {let called falsetry {thenable.then.call(thenable.target,(value: any) {if (called) returncalled truethis.resolve(value)},(reason: any) {if (called) returncalled truethis.reject(reason)})} catch (error) {if (!called) this.reject(error)}}thenTResult1 T, TResult2 never(onFulfilled?: ((value: T) TResult1 | PromiseLikeTResult1) | null | undefined,onRejected?: ((reason: any) TResult2 | PromiseLikeTResult2) | null | undefined): ShikaPromiseTResult1 | TResult2 {return new ShikaPromiseTResult1 | TResult2((resolve, reject) {const handleCallback (isFulfilled: boolean) {scheduleMicrotask(() {const callback isFulfilled ? onFulfilled : onRejectedconst data isFulfilled ? this.value : this.reasonif (typeof callback ! function) {if (isFulfilled) {resolve(data as TResult1)} else {reject(data)}return}try {const result callback(data)resolve(result)} catch (error) {reject(error)}})}switch (this.state) {case PromiseState.fulfilled:handleCallback(true)breakcase PromiseState.rejected:handleCallback(false)breakdefault:this.fulfilledHandlers.push(() handleCallback(true))this.rejectedHandlers.push(() handleCallback(false))}})}catchTResult never(onRejected?: ((reason: any) TResult | PromiseLikeTResult) | null | undefined): ShikaPromiseT | TResult {return this.then(null, onRejected)}finally(onFinally?: (() void) | null | undefined): ShikaPromiseT {return this.then((value) {onFinally?.()return value},(reason) {onFinally?.()throw reason})}static resolveT(value: T | PromiseLikeT): ShikaPromiseT {return value instanceof ShikaPromise ? value : new ShikaPromise((resolve) resolve(value))}static rejectT never(reason?: any): ShikaPromiseT {return new ShikaPromise((_, reject) reject(reason))}static wait(): ShikaPromisenever {return new ShikaPromise(() {})}cancel(): ShikaPromisenever {return new ShikaPromise(() {})}static deferredT() {let resolve!: (value: T | PromiseLikeT) voidlet reject!: (reason?: any) voidconst promise new ShikaPromiseT((res, rej) {resolve resreject rej})return { promise, resolve, reject }}}module.exports ShikaPromise
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

单页网站仿制教程家在深圳光明

目录已开发项目效果实现截图关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!已开发…

张小明 2026/1/4 23:47:37 网站建设

制作游戏需要什么技术旺道优化软件

为什么刚走出校园的应届生,能直接斩获百万年薪Offer? 为什么不少35、40的资深程序员,不仅无惧年龄焦虑,还能持续拿着高薪?2025年猎聘网的一则招聘信息刷爆行业圈——某头部AI芯片企业面向算法工程师岗位,直…

张小明 2026/1/5 11:44:50 网站建设

网站建设容易吗wordpress歌词插件

让用户满意的网络配置指南 在网络配置过程中,为了让用户获得更好的体验,我们需要对多个方面进行细致的设置和优化。以下将详细介绍用户配置文件修改、网络默认用户配置文件使用、打印机驱动自动下载安装等相关内容。 1. 用户配置文件修改 为了优化用户配置文件的使用和管理…

张小明 2026/1/3 7:14:47 网站建设

海南省建设信息官方网站众创空间那个网站做的好

OpenArm开源机械臂:构建下一代人机协作平台的完整指南 【免费下载链接】OpenArm OpenArm v0.1 项目地址: https://gitcode.com/gh_mirrors/op/OpenArm 你是否曾经面临这样的困境:商用机械臂价格高昂且缺乏定制空间,而现有开源方案在安…

张小明 2025/12/30 0:36:40 网站建设

做公司网站的步骤建设网站流程图

Psi4量子化学计算:解决实际科研问题的5大核心模块 【免费下载链接】psi4 Open-Source Quantum Chemistry – an electronic structure package in C driven by Python 项目地址: https://gitcode.com/gh_mirrors/ps/psi4 当你面对复杂的分子体系需要深入理解…

张小明 2026/1/6 20:04:30 网站建设

html5手机网站案例民宿网站建设 世家

第一章:系统核心硬件架构与选型 基于单片机的住宅防火防盗报警系统以“全方位监测、快速响应”为设计核心,采用“STC89C52RC单片机多传感检测模块报警执行模块交互模块”的硬件架构,适配普通住宅、小型公寓的安全防护需求。主控芯片选用STC89…

张小明 2026/1/6 15:51:35 网站建设