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简单实现的更多相关文章

  1. es6 Promise简单介绍

    promise的基本用法 promise执行多步操作非常好用,那我们就来模仿一个多步操作的过程,那就以吃饭为例吧.要想在家吃顿饭,是要经过三个步骤的. 洗菜做饭. 坐下来吃饭. 收拾桌子洗碗. 这个过 ...

  2. ES6 promise简单实现

    基本功能实现: function Promise(fn){ //需要一个成功时的回调 var doneCallback; //一个实例的方法,用来注册异步事件 this.then = function ...

  3. 理解Promise简单实现的背后原理

    在写javascript时我们往往离不开异步操作,过去我们往往通过回调函数多层嵌套来解决后一个异步操作依赖前一个异步操作,然后为了解决回调地域的痛点,出现了一些解决方案比如事件订阅/发布的.事件监听的 ...

  4. Promise简单实现--摘抄

    Promise 看了些promise的介绍,还是感觉不够深入,这个在解决异步问题上是一个很好的解决方案,所以详细看一下,顺便按照自己的思路实现一个简单的Promise. Promise/A+规范: 首 ...

  5. 小程序 请求Promise简单封装

    最近做小程序在调用后台接口的时候感觉总写很长一串,很冗杂.非常想念vue中promise封装的写法,于是自己初步封装了一下. 1.url 接口地址 2.headers请求头 3. params 请求参 ...

  6. es6 promise 简单总结

    话不多说,直捣主题. promise用途:异步编程的一种解决方案. 优点:比传统的解决方案——回调函数和事件——更合理和更强大. 三种状态:pending(进行中).fulfilled(已成功)和re ...

  7. Promise简单实现(正常思路版)

    转自: http://www.jianshu.com/p/473cd754311f Promise 看了些promise的介绍,还是感觉不够深入,这个在解决异步问题上是一个很好的解决方案,所以详细看一 ...

  8. JavaScript笔记 #06# Promise简单例子

    索引 回调版本 Promise版本1 Promise版本2 Notes 参考资料: Promise JavaScript Promise:简介 你去书店借书,按照异步的套路,剧情如下↓ 你:“老板,有 ...

  9. [javascript] Promise简单学习使用

    原文地址:http://www.cnblogs.com/dojo-lzz/p/4340897.html 解决回调函数嵌套太深,并行逻辑必须串行执行,一个Promise代表一个异步操作的最终结果,跟Pr ...

  10. 关于Promise 简单使用理解

    在学一个新的知识的时候,我的总结是首先要具备相关的基础知识,其次就是可以静下心来能看进去去理解,看一两遍不懂,就看四五遍,甚至六七遍,每一遍都认真努力理解,总会学会的. Promise是一个构造函数, ...

随机推荐

  1. win10和linux引导问题(没有系统选择界面)

    由于最近学习嵌入式和c模块化编程,需要使用Linux系统,但是编程之外,WIN10还是主力系统,决定装双系统. 往常一样,百度装双系统方法,网上千篇一律,大都一个套路. 首先,WIN10 下,新开一个 ...

  2. iodine dig A

    (base) bonelee@bonelee-VirtualBox:~/Desktop$ dig paeadgpy.abc.com @45.32.247.94 ; <<>> D ...

  3. 项目Beta冲刺随笔集合

    班级:软件工程1916|W 作业:项目Beta冲刺 团队名称:SkyReach 目标:完成项目Beta版本 项目Github地址 评审表 团队博客汇总 队员学号 队员姓名 个人博客地址 备注 2216 ...

  4. WHAT IS GAME-BASED LEARNING?

    https://www.growthengineering.co.uk/what-is-game-based-learning/ Gamification and game-based learnin ...

  5. 电商平台+keepalived高可用

    192.168.189.131 电商平台 192.168.189.129 MySQL主192.168.189.130 MySQL备192.168.189.181 VIP 配置MySQL为互为主从并结合 ...

  6. java的多线程之入门

    一.java多线程基本概念 调用run():在主线程调用子线程的run()方法会中断主线程等到子线程执行完毕之后再执行主线程. 调用start():在主线程中执行子线程的start()后会与主线程同步 ...

  7. 彻底理解C++指针

    目录 目录 1 1. 概念 1 1.1. 双指针 1 1.2. 指针数组 1 1.3. 数组指针 1 1.4. 常见指针定义解读 1 2. 区别 2 3. 兼容性 2 4. 为何列数须相等? 2 5. ...

  8. A1102 | 反转二叉树

    #include <stdio.h> #include <memory.h> #include <math.h> #include <string> # ...

  9. luogu P4248 [AHOI2013]差异 SAM

    luogu P4248 [AHOI2013]差异 链接 luogu 思路 \(\sum\limits_{1<=i<j<=n}{{len}(T_i)+{len}(T_j)-2*{lcp ...

  10. 服务器使用bbr加速配置

    服务器内核升级: 以centos7为例,配置之前可使用以下命令查看内核版本,若是4.0以上则无需对内核升级: uname -r 对内核升级的方法: 直接使用以下命令进行内核版本的下载: rpm --i ...