手写简易版Promise
实现一个简易版 Promise
在完成符合 Promise/A+ 规范的代码之前,我们可以先来实现一个简易版 Promise
,因为在面试中,如果你能实现出一个简易版的 Promise
基本可以过关了。
那么我们先来搭建构建函数的大体框架
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected' function MyPromise(fn) {
const that = this
that.state = PENDING
that.value = null
that.resolvedCallbacks = []
that.rejectedCallbacks = []
// 待完善 resolve 和 reject 函数
// 待完善执行 fn 函数
}
- 首先我们创建了三个常量用于表示状态,对于经常使用的一些值都应该通过常量来管理,便于开发及后期维护
- 在函数体内部首先创建了常量
that
,因为代码可能会异步执行,用于获取正确的this
对象 - 一开始
Promise
的状态应该是pending
value
变量用于保存resolve
或者reject
中传入的值resolvedCallbacks
和rejectedCallbacks
用于保存then
中的回调,因为当执行完Promise
时状态可能还是等待中,这时候应该把then
中的回调保存起来用于状态改变时使用
接下来我们来完善 resolve
和 reject
函数,添加在 MyPromise
函数体内部
function resolve(value) {
if (that.state === PENDING) {
that.state = RESOLVED
that.value = value
that.resolvedCallbacks.map(cb => cb(that.value))
}
} function reject(value) {
if (that.state === PENDING) {
that.state = REJECTED
that.value = value
that.rejectedCallbacks.map(cb => cb(that.value))
}
}
这两个函数代码类似,就一起解析了
- 首先两个函数都得判断当前状态是否为等待中,因为规范规定只有等待态才可以改变状态
- 将当前状态更改为对应状态,并且将传入的值赋值给
value
- 遍历回调数组并执行
完成以上两个函数以后,我们就该实现如何执行 Promise
中传入的函数了
try {
fn(resolve, reject)
} catch (e) {
reject(e)
}
- 实现很简单,执行传入的参数并且将之前两个函数当做参数传进去
- 要注意的是,可能执行函数过程中会遇到错误,需要捕获错误并且执行
reject
函数
最后我们来实现较为复杂的 then
函数
MyPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected =
typeof onRejected === 'function'
? onRejected
: r => {
throw r
}
if (that.state === PENDING) {
that.resolvedCallbacks.push(onFulfilled)
that.rejectedCallbacks.push(onRejected)
}
if (that.state === RESOLVED) {
onFulfilled(that.value)
}
if (that.state === REJECTED) {
onRejected(that.value)
}
}
首先判断两个参数是否为函数类型,因为这两个参数是可选参数
当参数不是函数类型时,需要创建一个函数赋值给对应的参数,同时也实现了透传,比如如下代码
// 该代码目前在简单版中会报错
// 只是作为一个透传的例子
Promise.resolve(4).then().then((value) => console.log(value))接下来就是一系列判断状态的逻辑,当状态不是等待态时,就去执行相对应的函数。如果状态是等待态的话,就往回调函数中
push
函数,比如如下代码就会进入等待态的逻辑new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 0)
}).then(value => {
console.log(value)
})
以上就是简单版 Promise
实现
手写简易版Promise的更多相关文章
- 手写简易版RPC框架基于Socket
什么是RPC框架? RPC就是远程调用过程,实现各个服务间的通信,像调用本地服务一样. RPC有什么优点? - 提高服务的拓展性,解耦.- 开发人员可以针对模块开发,互不影响.- 提升系统的可维护性及 ...
- Netty核心组件介绍及手写简易版Tomcat
Netty是什么: 异步事件驱动框架,用于快速开发高i性能服务端和客户端 封装了JDK底层BIO和NIO模型,提供高度可用的API 自带编码解码器解决拆包粘包问题,用户只用关心业务逻辑 精心设计的Re ...
- mybatis(八)手写简易版mybatis
一.画出流程图 二.设计核心类 二.V1.0 的实现 创建一个全新的 maven 工程,命名为 mebatis,引入 mysql 的依赖. <dependency> <groupId ...
- 手写简易的Mybatis
手写简易的Mybatis 此篇文章用来记录今天花个五个小时写出来的简易版mybatis,主要实现了基于注解方式的增删查改,目前支持List,Object类型的查找,参数都是基于Map集合的,可以先看一 ...
- JDK动态代理深入理解分析并手写简易JDK动态代理(下)
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...
- JDK动态代理深入理解分析并手写简易JDK动态代理(上)
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...
- 【教程】手写简易web服务器
package com.littlepage.testjdbc; import java.io.BufferedReader; import java.io.FileReader; import ja ...
- 手写简易SpringMVC
手写简易SpringMVC 手写系列框架代码基于普通Maven构建,因此在手写SpringMVC的过程中,需要手动的集成Tomcat容器 必备知识: Servlet相关理解和使用,Maven,Java ...
- JavaScript之Promise实现原理(手写简易版本 MPromise)
手写 Promise 实现 Promise的基本使用 Promise定义及用法详情文档:Promise MAD文档 function testPromise(param) { return new P ...
随机推荐
- Linux——vim操作
查看文件:vim 文件名 进入vim命令后: Shift+g:到达文件底部 /搜索内容:搜索文件中字符串:点击“N”键,查看下一个搜索内容位置
- css实现手机端导航栏左右滑动
<html> <head> <meta charset="utf-8"> <meta name="viewport" ...
- zepto快速入门教程
* zepto* 特点:1.体积8kb2.针对移动端的框架3.语法同jquery大部分一样,都是$为核心函数4.目前功能完善的框架体积最小的左右* 同jquery相似的语法核心:$--作为函数使用参数 ...
- C#中的out关键字
在一个方法里面使用out关键字的时候这个方法中作为out关键字之后的参数会被返回出去:调用这个方法的时候需要先有一个变量来承接这个传递出来.已经被该方法改动过的参数,并且要记得传实参的时候前面带上ou ...
- C#中的any和all
any是判断列表里面是否有哪怕一个: all是判断列表里面是否每一项都包含:
- Java 泛型与集合
1.List练习,请用泛型的写法来完成. 已知有一个Worker 类如下: public class Worker { private int age; private String name; p ...
- 利用pandas进行数据子集的获取
- 微服务项目的docker自动化部署流程
目录 微服务的Docker自动化部署 制作JDK1.8的Docker镜像 Docker常用命令介绍 制作image的一般流程 将本地的image上传至私人仓库 使用Maven插件实现自动化docker ...
- 引入mybatis-plus报 Invalid bound statement错误怎么办,动动手指改一个地方就行
错误 Mybatis-Plus (简称MP) 是mybatis的一个增强工具,在mybatis的基础上只做增强不做改变,简化了开发效率.其实就是帮我们封装了一些简单的curd方法,可以直接调用,不必再 ...
- CVE-2020-0796永恒之黑复现POC EXP以及修复方案
描述: 北京时间3月12日,针对最新披露的SMB远程代码执行漏洞(CVE-2020-0796),微软官方发布了针对Windows 10/Server禁用SMBv3(SMB 3.1.1版本)协议压缩的安 ...