模拟Promise的功能
模拟Promise的功能, 按照下面的步骤,一步一步
1. 新建是个构造函数
2. 传入一个可执行函数 函数的入参第一个为 fullFill函数 第二个为 reject函数; 函数立即执行, 参数函数异步执行
3. 状态一旦更改就不可以变更 只能 pending => fulfilled 或者 pending => rejected
4. then 的时候要处理入参的情况 successCallback 和failCallback 均可能为非函数
- 默认的 failCallback 一定要将异常抛出, 这样下一个promise便可将其捕获 异常冒泡的目的
5. then 中执行回调的时候要捕获异常 将其传给下一个promise
- 如果promise状态未变更 则将回调方法添加到对应队列中
- 如果promise状态已经变更 需要异步处理成功或者失败回调
- 因为可能出现 回调结果和当前then返回的Promise一致 从而导致死循环问题
6. catch只是then的一种特殊的写法 方便理解和使用
7. finally 特点
- 不过resolve或者reject都会执行
- 回调没有参数
- 返回一个Promise 且值可以穿透到下一个then或者catch
8. Promise.resolve, Promise.reject 根据其参数返回对应的值 或者状态的Promise即可
9. Proise.all 特点
- 返回一个Promise
- 入参是数组 resolve的情况下出参也是数组 且结果顺序和调用顺序一致
- 所有的值或者promise都完成才能resolve 所有要计数
- 只要有一个为reject 返回的Promise便reject
10. Proise.race 特点
- 返回一个Promise
- 入参是数组 那么出参根据第一个成功或者失败的参数来确定
- 只要有一个resolve 或者reject 便更改返回Promise的状态
const PENDING = 'pending' //等待
const FULFILLED = 'fulfilled' //成功
const REJECTED = 'rejected' //失败 const fulfilledCallback = [] //成功回调函数
const rejectedCallback = [] //失败回调函数 class MyPromise { constructor (executor) { try{
executor(this.resolve, this.reject)
} catch (e){
this.reject(e)
}
} status = PENDING//promise的状态
value = undefined//成功之后的值
reason = undefined//失败之后的值
fulfilledCallback = [] //成功回调函数
rejectedCallback = [] //失败回调函数
resolve = value => {
//如果状态不是等待, 阻止程序继续往下执行
if(this.status !== PENDING){
return
}
this.status = FULFILLED
this.value = value
//判断成功回调是否存在,如果存在, 调用
// this.fulfilledCallback && this.fulfilledCallback(this.value)
while(this.fulfilledCallback.length) this.fulfilledCallback.shift()() }
reject = reason => {
//如果状态不是等待, 阻止程序继续往下执行
if(this.status !== PENDING){
return
}
this.status = REJECTED
this.reason = reason
//判断失败回调是否存在,如果存在, 调用
// this.rejectedCallback && this.rejectedCallback(this.reason)
while(this.rejectedCallback.length) this.rejectedCallback.shift()()
}
then = (fulfilledCallback, rejectedCallback) => {
fulfilledCallback = fulfilledCallback ? fulfilledCallback : value => value
rejectedCallback = rejectedCallback ? rejectedCallback : reason => {throw reason}
let promise2 = new MyPromise((resolve, reject) => { //判断状态
if(this.status === FULFILLED){
setTimeout(() => {
try {
//判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
//如果是普通值,直接调用resolve
let x = fulfilledCallback(this.value)
//外面加载完,才能获取到promise2,用异步解决
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
} },0) }else if(this.status === REJECTED){ setTimeout(() => {
try {
//判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
//如果是普通值,直接调用resolve
let x = rejectedCallback(this.reason)
//外面加载完,才能获取到promise2,用异步解决
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
} },0)
}else{
//等待状态
this.fulfilledCallback.push(() => {
setTimeout(() => {
try {
//判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
//如果是普通值,直接调用resolve
let x = fulfilledCallback(this.value)
//外面加载完,才能获取到promise2,用异步解决
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
} },0)
});
this.rejectedCallback.push(() => {
setTimeout(() => {
try {
//判断x 传过来的可能是promise,先查看promise返回的结果,在决定是用resolve还是reject,
//如果是普通值,直接调用resolve
let x = rejectedCallback(this.reason)
//外面加载完,才能获取到promise2,用异步解决
resolvePromise(promise2,x,resolve, reject)
} catch (error) {
reject(error)
} },0)
});
}
})
return promise2
} static all (array) {
let result= []
let index = 0; return new MyPromise((resolve, reject) => { function addData (key, value) {
result[key] = value
index++
if (index === array.length) {
resolve(result)
}
} for (let i = 0; i < array.length; i++) { if (array[i] instanceof MyPromise) {
//promise对象
array[i].then(value => addData(i, value), reason => reject(reason))
} else {
//普通值, 放到数组里
addData(i, array[i])
}
}
}) } static resolve (value) {
if(value instanceof MyPromise) return value
return new MyPromise(resolve => resolve(value)) } finally (callback) {
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
return MyPromise.resolve(callback()).then(() => {throw reason})
}) } catch (rejectedCallback) {
return this.then(undefined, rejectedCallback)
} } function resolvePromise(promise2,x,resolve, reject){ if(x === promise2){
return reject(new TypeError('啦啦啦啦'))
}
if(x instanceof MyPromise){
//是promise
//往下直接传
x.then(resolve,reject)
}else{
//普通值
resolve(x)
}
} module.exports = MyPromise;
模拟Promise的功能的更多相关文章
- Java基础面试操作题:线程同步代码块 两个客户往一个银行存钱,每人存三十次一次存一百。 模拟银行存钱功能,时时银行现金数。
package com.swift; public class Bank_Customer_Test { public static void main(String[] args) { /* * 两 ...
- ListView模拟微信好友功能
ListView模拟微信好友功能 效果图: 分析: 1.创建listView 2.创建数据 3.创建适配器 将数据放到呈现数据的容器里面. 将这个容器(带数据)连接适配器. 其实是直接在我们自己写的a ...
- 编写函数模拟strcpy()函数功能
strcpy(字符数组1,字符串2) strcpy( )用于将字符串2复制到字符数组1中 /* strcpy(字符数组1,字符串2) strcpy( )用于将字符串2复制到字符数组1中 模拟strcp ...
- TCP模拟QQ聊天功能
需求: 模拟qq聊天功能:实现客户端与服务器(一对一)的聊天功能,客户端首先发起聊天,输入的内容在服务器端和客户端显示,然后服务器端也可以输入信息,同样信息在客户端和服务端显示. 提示: 客户端 1) ...
- 标准IO的简单应用,动静态库,读取系统时间并打印,模拟ls -l功能
2015.2.27星期五,小雨 标准IO实现的复制功能: #include <stdio.h>#include <errno.h> #define N 64 int main( ...
- js模拟实现继承功能
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 简单模拟 Promise
class promise { constructor(fn) { this.data = null; this.err = null; this.isPromise = false; this.er ...
- 在VFP6中模拟CursorAdapter的功能
这个是我在2002年做的一个VFP程序中实现的方法, 现在看来功能和VFP8,9中的CursorAdapter非常相似, 因为属性设置有许多相同的地方,我甚至怀疑CA就是就是在这样的基础上再包装出来的 ...
- 模拟storage copy 功能失败的记录
试验设想: 机器1: alter database begin backup 然后,在oracle仍然活动的状态下,将$ORACLE_BASE目录全部压缩拷贝到机器2 机器2: startup:失败 ...
- PyQt4 模拟记事本基本功能(保存,打开文件)
完成功能: 1. 默认[保存]按钮enable 2. 修改文本的内容后,[enable] 3. 解决字符乱码问题:utf-8 4. 提示:如果修改了文件没有保存的时候,又尝试打开新的文件,给出相关的提 ...
随机推荐
- 使用PBIS将Linux加入域
使用PBIS将Linux加入域 很多企业已经部署的微软的活动目录,为了方便管理,可以把Linux加入域.网上流传了很多把Linux加入域的方法,感觉比较复杂,并且似乎并没有真正的加入域.只是完成 ...
- Coprime
Coprime 前置芝士 莫比乌斯反演 正文 首先,我们来分析题意. 题目中给出 \(n\) 个人,每个人有一个编号 \(k\) ,要求我们从中选出 \(3\) 个人,三人编号分别为 \(k_a\) ...
- C# 中的那些锁,在内核态都是怎么保证同步的?
一:背景 1. 讲故事 其实这个问题是前段时间有位朋友咨询我的,由于问题说的比较泛,不便作答,但想想梳理一下还是能回答一些的,这篇就来聊一聊下面这几个锁. Interlocked AutoResetE ...
- Docker与Containerd使用区别
文章转载自:https://cloud.tencent.com/developer/article/1984040 Kubernetes 在 1.24 版本里弃用并移除 docker shim,这导致 ...
- CI/CD集成
文章转载自:https://kuboard.cn/guide/cicd/ 下图展示了当前比较典型的持续构建集成的一种做法. 在是否自动将最新版本部署到 Kubernetes 环境这个问题上,可能会有多 ...
- DirectPV-----文章内容有待进一步实践完善
GitHub文档地址:https://github.com/minio/directpv DirectPV是用于直连存储的CSI驱动程序.从更简单的意义上讲,它是一个分布式持久卷管理器,而不是像SAN ...
- siteServer CMS知识点
1.结构说明 (1) 网站目录说明: a. 一个SitesServer后台只能建立一个主站,但可以建立多个子站,主站目录就是项目的根目录: b. 而子站的目录呢?是在主站目录下建立相应名称的目 ...
- Codeforces Round #708 (Div. 2)
A题被hack,A题很简单,其实题目没看懂,直接看样例做的. B题题意是以为懂了,但是样例一直看不懂. 经验:要两两相加能被一个m整除数组sum最少,利用他们的余数就可以设为a[x], x是余数,如果 ...
- linux操作系统运行一个java程序并外网访问
(一)安装jdk 1.新建文档java : mkdir java 2.进入java并且下载jdk 下载jdk : wget --no-check-certificate --no-cooki ...
- Java编程基础——敬请期待!!!
变量 数据类型 条件判断 循环 函数 类 Java特性