promise简单实现
function isFunction(fn){
return Object.prototype.toString.call(fn) === '[object Function]';
} let ST = {
pending: 0,
resolved: 1,
rejected: 2
} function Promise(fn){
let self = this;
self.status = ST.pending;
self.value = '';
self.reason = '';
self.resolveFns = [];
self.rejectFns = []; //setTimeout延迟执行,将reslove执行放在下个循环,保证后续then方法先于它执行,不会出现前面已经resolve了,后面的then还没push进resolveFns数组
function resolve(val){
setTimeout(() => {
if(self.status == ST.pending){
self.status = ST.resolved;
self.value = val;
//用数组保存回调,是为了处理一个promise挂载多个then的情况
//注意不是链式,这种场景很少出现
/*
形如:
promise.then(resolve1,reject1)
promise.then(resolve2,reject2)
promise.then(resolve3,reject3)
*/
//在链式调用中,该数组通常只会有一个项,就是当前promise的下一个then里面的resolve函数
//且每次执行,通常都是一个新Promise的resolve数组
self.resolveFns.forEach(fn => fn());
}
})
} function reject(val){
setTimeout(() => {
if(self.status == ST.pending){
self.status = ST.rejected;
self.reason = val;
self.rejectFns.forEach(fn => fn());
}
})
} //执行出问题,直接reject,Promise的错误默认不会抛出到全局
try{
fn(resolve,reject);
}
catch(err){
reject(err);
}
} Promise.prototype.then = function(onResolve,onReject){
let self = this; //then每次执行都返回一个新的Promise,then方法要处理前一个promise的三种状态
return new Promise(function(resolve,reject){
function handle(value,thenFn){
let res = isFunction(thenFn) && thenFn(value) || value;
if(res instanceof Promise){
res.then(resolve,reject);
}
else{
resolve(res);
}
} //处理三种状态
//fn函数体里,如果有错误; 会执行try catch里的 reject方法,执行then this.state就是rejected
//如果没错误且没异步,resolve this.state就是resolved
//如果没错误且有异步,this.state就是pending
if(self.status == ST.pending){
self.resolveFns.push(resloveHandle);
self.rejectFns.push(rejectHandle);
}
else if(self.status == ST.resolved){
self.handle(self.value,onResolve);
}
else if(this.status == ST.rejected){
self.handle(self.reason,onReject);
}
})
} Promise.prototype.catch = function(onReject){
return this.then(undefined, onReject);
} //finally不是promise的末尾,后面还可以有then,所以value和reason必须可以向下传递
Promise.prototype.finally = function(fn){
let P = this.constructor;
return this.then(
value => P.resolve(fn()).then(() => value),
reason => P.resolve(fn()).then(() => throw reason);
)
} //done作为promise的末尾,用于收集所有可能的报错,catch方法捕捉所有错误,并抛出
Promise.prototype.done = function(resolve,reject){
return this.then(resolve, reject).catch(function(reason){
setTimeout(function(){
throw reason;
});
})
} Promise.resolve = function(val){
return new Promise((resolve) => {
resolve(val);
})
} Promise.reject = function(val){
return new Promise((resolve,reject) => {
reject(val);
})
} Promise.race = function(promises){
let len = promises.length; return new Promise(function(resolve,reject){
while(len--){
promises[len].then(resolve,reject);
}
})
} Promise.all = function(promises){
let len = promises.length,
results = []; return new Promise(function(resolve,reject){
//用一个数组收集单个promise执行后的结果,收集满数组所有结果,便是所有执行成功
function reslove(index){
return function(value){
results[index] = value;
if(results.length == len){
reslove(results);
}
}
} while(len--){
promises[len].then(resolve(len),reject);
}
})
}
promise简单实现的更多相关文章
- es6 Promise简单介绍
promise的基本用法 promise执行多步操作非常好用,那我们就来模仿一个多步操作的过程,那就以吃饭为例吧.要想在家吃顿饭,是要经过三个步骤的. 洗菜做饭. 坐下来吃饭. 收拾桌子洗碗. 这个过 ...
- ES6 promise简单实现
基本功能实现: function Promise(fn){ //需要一个成功时的回调 var doneCallback; //一个实例的方法,用来注册异步事件 this.then = function ...
- 理解Promise简单实现的背后原理
在写javascript时我们往往离不开异步操作,过去我们往往通过回调函数多层嵌套来解决后一个异步操作依赖前一个异步操作,然后为了解决回调地域的痛点,出现了一些解决方案比如事件订阅/发布的.事件监听的 ...
- Promise简单实现--摘抄
Promise 看了些promise的介绍,还是感觉不够深入,这个在解决异步问题上是一个很好的解决方案,所以详细看一下,顺便按照自己的思路实现一个简单的Promise. Promise/A+规范: 首 ...
- 小程序 请求Promise简单封装
最近做小程序在调用后台接口的时候感觉总写很长一串,很冗杂.非常想念vue中promise封装的写法,于是自己初步封装了一下. 1.url 接口地址 2.headers请求头 3. params 请求参 ...
- es6 promise 简单总结
话不多说,直捣主题. promise用途:异步编程的一种解决方案. 优点:比传统的解决方案——回调函数和事件——更合理和更强大. 三种状态:pending(进行中).fulfilled(已成功)和re ...
- Promise简单实现(正常思路版)
转自: http://www.jianshu.com/p/473cd754311f Promise 看了些promise的介绍,还是感觉不够深入,这个在解决异步问题上是一个很好的解决方案,所以详细看一 ...
- JavaScript笔记 #06# Promise简单例子
索引 回调版本 Promise版本1 Promise版本2 Notes 参考资料: Promise JavaScript Promise:简介 你去书店借书,按照异步的套路,剧情如下↓ 你:“老板,有 ...
- [javascript] Promise简单学习使用
原文地址:http://www.cnblogs.com/dojo-lzz/p/4340897.html 解决回调函数嵌套太深,并行逻辑必须串行执行,一个Promise代表一个异步操作的最终结果,跟Pr ...
- 关于Promise 简单使用理解
在学一个新的知识的时候,我的总结是首先要具备相关的基础知识,其次就是可以静下心来能看进去去理解,看一两遍不懂,就看四五遍,甚至六七遍,每一遍都认真努力理解,总会学会的. Promise是一个构造函数, ...
随机推荐
- springboot java.awt.AWTException: headless environment
修改启动类即可 @SpringBootApplicationpublic class SystemctlApplication { public static void main(String[] a ...
- Vuex之辅助函数
mapState.mapGetters.mapActions 如果我们不喜欢这种在页面上使用“this.$stroe.state.count”和“this.$store.dispatch('funNa ...
- C#中RadioButton选中和取消选中(一种没办法选中和未选中切换)
今天在做Winform 中RadioButton控件时,遇到一个小坑,虽然很简单,但是浪费我十分钟,感觉需要记录一下共勉. 问题描述:(RadioButton控件名为rbTime) 本来以为判断一下是 ...
- Js 日期字符串分别截取 年 月 日 时 分 秒
function shijiantime(times){ var timearr = times.replace(" ", ":").replace(/\:/g ...
- space-cloud 学习一 基本试用
space-cloud 是一个支持多数据库,以下是一个简单的基于官方文档的试用 使用docker-compose 运行 环境准备 下载docker-compose文件 wget https://raw ...
- Python 检查代码占用内存 工具和模块
只介绍简单的使用, 更多使用方法请查看官方文档 tracemalloc 官方文档 tracemalloc文档地址 使用 import tracemalloc tracemalloc.start() # ...
- Python中的异步任务队列 arq
引言 最近在用 sanic 写东西,所有涉及到IO阻塞的代码都需要用 aio 的模块,好在近年来 asyncio 生态圈发展的还算不错,该有的都有 ~ 近期业务中 登录/注册 业务涉及的很复杂(涉及到 ...
- SQLSERVER获取数据库中的所有表的名称、表中所有字段的属性
1.查询数据库中的所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: SELECT Name FR ...
- css选择指定元素
.butSpan:){ margin-left: 10px; } nth-child(n+2)括号内可以是公式 可是是数字
- Unity制作棋牌手游之斗地主
目录 大小7.2GB,MP4格式 扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop135452397.taobao.com/ 联系店主