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. web api .net C# mvc API返回XML文档的解析并取值

    [HttpGet] public System.Net.Http.HttpResponseMessage GetNotify() { var xmlstring = @" <xml&g ...

  2. Android Studio在代码重构中的妙用

    代码重构几乎是每个程序员在软件开发中必须要不断去做的事情,以此来不断提高代码的质量.Android Stido(以下简称AS)以其强大的功能,成为当下Android开发工程师最受欢迎的开发工具,也是A ...

  3. url 组成

  4. JMeter5.1开发Java协议接口脚本【待完成】

    JMeter5.1开发Java协议接口脚本

  5. python 的 lambda使用笔记

    无参数匿名函数: f=lambda: none f() 输出:none 带参数匿名函数: 带一个参数: f=lambda x:x+1 f(1) 输出:2 带多个参数: f=lambda a,b,c:a ...

  6. MySQL中Count函数的参数该传入什么样的值?

    MySQL中Count函数的参数该传入什么样的值? 查询用户表中总记录 用户表中信息如下: 1.SELECT COUNT(*) FROM USER 结果为:3条 2.  SELECT COUNT(us ...

  7. 事物分析、静态分析(结构分析)与UML

    事物分析: 1)要素分析: 2)结构(组织.关系)分析: 符合软件中的数据库观点和UML观点: 符合数据结构的观点. 符合由点到面的观点. 将关系和元素提到了同等重要的地位. 符合哲学中普遍联系的观点 ...

  8. MongoDB 查看集合与索引状态命令

    1.查看集合状态命令 MongoDB Enterprise > db.trs_action_dzwl_zm.stats() 2.查看索引状态命令 MongoDB Enterprise > ...

  9. 4GB以上超大文件上传和断点续传服务器的实现

    随着视频网站和大数据应用的普及,特别是高清视频和4K视频应用的到来,超大文件上传已经成为了日常的基础应用需求. 但是在很多情况下,平台运营方并没有大文件上传和断点续传的开发经验,往往在网上找一些简单的 ...

  10. BZOJ 1818: [Cqoi2010]内部白点 扫描线+树状数组

    问题转化为求每一个极长横线段与极长纵线段的交点个数. 这个东西用扫描线+树状数组维护一下就可以了. code: #include <cstdio> #include <algorit ...