参考Promise 的  官方规范  https://promisesaplus.com/

Promise 其实就是一个状态机

它只有两种状态变化 pending    =》   fulfilled

         pending    =》   rejected

并且状态一旦发生变化后就不会再改变

我们用es5来实现下

先写个架子, 并测试下:

function myPromise(executor) {
var _this = this; // 保存当前的函数上下文
_this.status = 'pending'; // 初始状态
_this.resolveValue = null; // resolve初始值
_this.rejectValue = null; // reject初始值
function resolve(value) {
if (_this.status == 'pending') {
_this.status = 'Fulfilled';
_this.resolveValue = value;
}
}
function reject(reason) {
if (_this.status == 'pending') {
_this.status = 'Fulfilled';
_this.rejectValue = reason;
}
}
try { // 捕获错误
executor(resolve, reject)
} catch (e){
reject(e);
}
}
myPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
if (_this.status == 'Fulfilled') {
onFulfilled(_this.resolveValue)
}
if (_this.status == 'Rejected') {
onRejected(_this.rejectValue)
}
}; var p = new myPromise((resolve, reject) => {
resolve('I am handsome');
throw Error('捕获错误')
});
p.then((data) => {
console.log(data)
}, (err) => {
console.log(err)
} );

结果:

它先执行resolve   状态 变为   Fulfilled    ,

然后报错 ,执行reject , 由于此时状态不是pending, 状态还是Fulfilled

Promise的核心是处理异步,

现在我们的代码并不能等待状态的改变,

接下来我们加上处理异步操作的功能, 并测试下

function myPromise(executor) {
var _this = this; // 保存当前的函数上下文
_this.status = 'pending'; // 初始状态
_this.resolveValue = null; // resolve初始值
_this.rejectValue = null; // reject初始值
_this.resolveCallbackList = []; // 存resolve的回调
_this.rejectCallbackList = []; // 存reject的回调
function resolve(value) {
if (_this.status == 'pending') {
_this.status = 'Fulfilled';
_this.resolveValue = value;
// 状态改变执行存的回调
_this.resolveCallbackList.forEach(function(ele){
if (ele) {
ele();
}
})
}
}
function reject(reason) {
if (_this.status == 'pending') {
_this.status = 'Rejected';
_this.rejectValue = reason;
// 状态改变执行存的回调
_this.rejectCallbackList.forEach(function(ele){
if (ele) {
ele();
}
})
}
}
try { // 捕获错误
executor(resolve, reject)
} catch (e){
reject(e);
}
}
myPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
if (_this.status == 'Fulfilled') {
onFulfilled(_this.resolveValue)
}
if (_this.status == 'Rejected') {
onRejected(_this.rejectValue)
}
// 等待状态时把回调存起来,状态改变再触发
if (_this.status == 'pending') {
_this.resolveCallbackList.push(function () {
onFulfilled(_this.resolveValue)
});
_this.rejectCallbackList.push(function () {
onRejected(_this.rejectValue)
});
}
}; var p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('I am handsome');
}, 0);
// throw Error('捕获错误')
});
p.then((data) => {
console.log(data)
}, (err) => {
console.log(err)
} );

结果:

自己写一个Promise的更多相关文章

  1. 【原】手写一个promise

    上一篇文章中,我们介绍了Promise的基本使用,在这篇文章中,我们试着自己来写一个Promise,主要是学习Promise的内部机制,学习它的编程思想. !!!备注:本文写的不好,仅供自己学习之用, ...

  2. 掘金转载-手写一个Promise

    目录 一 什么是Promise ? 二 Promises/A+ 规范 2.1 术语 2.2 基本要求 2.2.1. Promise的状态 2.2.2. Then 方法 2.3 简易版实践 2.4 进一 ...

  3. 手写一个Promise/A+,完美通过官方872个测试用例

    前段时间我用两篇文章深入讲解了异步的概念和Event Loop的底层原理,然后还讲了一种自己实现异步的发布订阅模式: setTimeout和setImmediate到底谁先执行,本文让你彻底理解Eve ...

  4. 面试----你可以手写一个promise吗

    参考:https://www.jianshu.com/p/473cd754311f <!DOCTYPE html> <html> <head> <meta c ...

  5. 手写一个promise

    Promise A+ 规范:https://promisesaplus.com/ 注:以下代码没有通过 promises-aplus-tests 的全部测试,但基本功能还是全的( 测试结果: 864 ...

  6. 只会用就out了,手写一个符合规范的Promise

    Promise是什么 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Prom ...

  7. 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise

    本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...

  8. 请手写代码实现一个promise

    第一步:promise的声明 class Promise{ // 构造器 constructor(executor){ // 成功 let resolve = () => { }; // 失败 ...

  9. 操刀 requirejs,自己动手写一个

    前沿 写在文章的最前面 这篇文章讲的是,我怎么去写一个 requirejs . 去 github 上fork一下,顺便star~ requirejs,众所周知,是一个非常出名的js模块化工具,可以让你 ...

随机推荐

  1. Hexo瞎折腾系列(9) - 网页标题崩溃特效

    前言 本系列的所有修改均基于本系列第一篇中的新增文件(譬如custom.js),请先自行阅读Hexo瞎折腾系列(1) - 准备工作与简单美化:并按照文章所说自行修改代码或文件. 为网页添加标题崩溃特效 ...

  2. Jmeter4.0---- HTTP请求默认值(15)

    1.说明 在线程组中,添加”HTTP请求默认值”,并填写 协议,服务器名称/IP ,端口号,编码等 ,之后该线程组中的所有请求,可以不用填写这几项,启动后会直接调用”HTTP请求默认值”中的数据,方便 ...

  3. 打印BroadcastReceiver的所有接受者

    Android中收到短信等事件都是通过广播发送给应用程序的,手机卫士等程序都是通过注册高优先级的BroadcastReceiver来实现短信防火墙等功能.对于我们来说很想知道系统中都有哪些程序注册了B ...

  4. IDEA右键新建时没有Java Class选项

    今天在IDEA中新建了一个maven工程,但是在我想要新建Class时发件右键菜单里竟然没有Java Class选项!如下图所示: 如上图红圈所示,我们可以根据对项目的任意目录进行这五种目录类型标注, ...

  5. AssetDatabase的方法总结

    AssetDatabase的方法总结 1.AssetDatabase.FindAssets public static string[] FindAssets(string filter);publi ...

  6. win7,docker安装后,创建虚拟机分配不了ip错误 err: exit status 255

    问题 win7装docker真麻烦,不如家里的win10爽.另外明明这是个很简单的操作,但是国内的解决方法有点落后,所以我写了个傻瓜式的. 有兴趣的可以直接看issue https://github. ...

  7. 查看Apache信息以用户htdoc位置

    查看Apache的相关信息:httpd -V 再从基本信息中取得DocumentRoot位置 less /etc/httpd/httpd.conf中查找DocumentRoot,即有静态文件存放的位置 ...

  8. 初学struts2-入门案列

    1.所需类库 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactI ...

  9. 《C#高效编程》读书笔记10-使用可选参数减少方法重载数量

    C#现在支持调用者一方使用具名参数(named parameter).类型中的名称也成为了公有接口的一部分.修改公有参数名称将有可能破坏掉调用者的代码. public void SetName(str ...

  10. hibernate课程 初探单表映射3-2 基本类型

    本节内容:(介绍基本类型) 1 数据类型 简介 2 时间类型 简介 3 时间类型 demo 1 hibernate类型 java类型   integer/int java.lang.Integer/i ...