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. 看TED演讲——Why you will fail to have a great career

    讲者的名字叫Larry Smith,看起来很严肃很认真,有点黑色幽默的意思,演讲风格是非常让人喜欢的. 拿来howie老师的说法,拉老师给的你为什么没有一个great career的原因: 1. 知道 ...

  2. Ubuntu不能使用passwd的--stdin的解决办法

    转载请注明来源https://www.cnblogs.com/sogeisetsu/p/11397648.html Ubuntu不能使用passwd的--stdin的解决办法 可以使用chpasswd ...

  3. 项目Beta冲刺 用户试用报告

    课程: 软件工程1916|W(福州大学) 作业要求: 项目Beta冲刺 团队名称: 火鸡堂 作业目标: 火鸡堂 队员学号 队员姓名 博客地址 备注 221600111 彼术向 http://www.c ...

  4. 洛谷P2882 [USACO07MAR]面对正确的方式Face The Right Way(贪心)

    题目描述 Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing forwar ...

  5. P5325 【模板】Min_25筛

    题意:定义积性函数f(x)f(x)f(x),且f(p^k)=p^k*(p^k−1)   (p是一个质数),求f(1)+f(2)+...f(n); 思路:板子题.重新打了一份装起来. /* 定义积性函数 ...

  6. hive中的日期转换函数

    1.unix时间戳转时间函数   语法: from_unixtime(bigintunixtime[, string format]) 返回值: string   说明: 转化UNIX时间戳(从197 ...

  7. dotnet core linux 接入支付宝H5支付,提示:System.PlatformNotSupportedException","Message":"'CspParameters' requires Windows Cryptographic API (CAPI), which is not available on this platform.

    用的官方提供的demo,实际上部署后却出现了上图的错误.和技术支持沟通无效后,走上了不归路. 在微软的github dotnet/core开源库提交了issue后,终于获得了解决.附上链接:https ...

  8. Tomcat不能访问ln -s软连接文件夹的前因后果

    为了部署方便,把webapps下的大文件(图片等资源)放到工程外,通过软连接的方式设置 命令最常用的参数是-s,具体用法是:ln -s 源文件 目标文件. ln -s /usr/local/pic/i ...

  9. 洛谷 P1993 小K的农场 题解

    每日一题 day55 打卡 Analysis 这是我们一次考试的T1,但我忘了差分约束系统怎么写了,所以就直接输出Yes混了60分 首先转化题目: 1:表示农场 a 比农场 b 至少多种植了 c 个单 ...

  10. [PHP] Laravel 5.5 使用备注

    laravel-5_5文档地址:https://laravelacademy.org/category/laravel-5_5 模板变量文档: https://laravelacademy.org/p ...