JavaScript实现一个简易的Promise

概念

这个主要是用于解决异步回调代码的噩梦,在ES6新增了Promise对象,可以直接使用。因为当多层异步代码存在时,可能会造成代码嵌套多层难以维护。比如:

todo(function () { todo(function () { todo(function () { //... }) }) })

其特点如下:

一旦创建实例则马上执行

状态只能从pending => resolved或者pending => rejected

状态一旦改变就不可更改

使用同步代码的方式来处理异步回调

当然这里只是实现了一个简易版,更详细的Promise对象信息你可以访问http://es6.ruanyifeng.com/#docs/promise

实现

const MyPromise = (function () {

const PENDING = "pending"; //初始状态

const RESOLVED = "resolved"; //已正确完成

const REJECTED = "rejected"; //抛出错误、失败

function F(fn) {

const that = this;

this.state = PENDING; //初始化状态

this.value = null; //保存传递的值

this.resolvedFnStack = []; //正确完成后要调用的方法栈

this.rejectedFnStack = []; //出现错误或者失败时要调用的方法栈

typeof fn === 'function' && fn(resolve, reject); //创建对象立刻调用传入的函数

function resolve(v) { //正确完成时,内部调用方法

if (that.state === PENDING) {

//首先要判断是否是初始状态,因为状态只有两种变化,不能逆转

that.value = v; //保存传递的值

that.state = RESOLVED; //将状态置为 已正确完成

that.resolvedFnStack.forEach(item =>

item(that.value)); //调用方法栈中的方法 } }

function reject(v) {

if (that.state === PENDING) {

that.value = v; that.state = REJECTED;

that.rejectedFnStack.forEach(item => item(that.value));

} } };

F.prototype.then = function(resolvedFn) { //异步执行,同步写法的关键。成功会调用的方法

if (typeof resolvedFn === 'function') {

if (this.state === RESOLVED) resolvedFn(this.value);

else this.resolvedFnStack.push(resolvedFn); }

return this;

};

F.prototype.catch = function(rejectedFn) {

if (typeof rejectedFn === 'function') {

if (this.state === REJECTED) rejectedFn(this.value);

else this.resolvedFnStack.push(rejectedFn);

}

return this; };

return F; })();


测试

new MyPromise((resolve, reject) => {

console.log("run");

console.log(new Date().getTime());

setTimeout(_ => { resolve("then run");

console.log(new Date().getTime()); }, 3000) })

.then(val => { console.log(val); });

// run

// 1556420154593

// then run

// 1556420157593

你可能感兴趣的:(JavaScript实现一个简易的Promise)