promise
相信大家都用过,解决回调地狱,更优雅的写代码。
简易版:
'use strict'
/**
* 思路:
* promise所有两种状态 resolve, reject
* pending是未完成状态
* 1. 从 pending 到 resolve 成功
* 2. 从 pedding 到 reject 失败
*
*/
function myPromise(constructor) {
let self = this;
self.stauts = 'pending'; // 未完成状态
self.value = undefined
self.resaon = undefined
function resolve(value) {
if (self.stauts === 'pending') {
self.value = value
self.stauts = 'resolved'// 成功
}
}
function reject(resaon) {
if (self.stauts === 'pending') {
self.resaon = resaon
self.resaon = 'rejected'// 失败
}
}
try {
constructor(resolve, reject)
} catch(e) {
reject(e)
}
}
myPromise.prototype.then = function(onFullfiled, onRejected) {
let self = this
switch(self.stauts) {
case 'resolved':
onFullfiled(self.value)
break
case 'rejected':
onRejected(self.resaon)
break
default:
break
}
}
测试:
// test
let promise = new myPromise(function(resolve, reject) {
resolve(1)
})
promise.then(function(s) {
console.log(s)
})
遵循 Promise A+ 规范:
// 定义一个promise构造函数
function MyPromise(resolver) {
// resolver 必须是一个函数
if (typeof resolver != "function") {
throw new TypeError("promise resolver if function");
}
// 如果当前对象是Promise,则直接返回
if (!(this instanceof Promise)) return new Promise(resolver);
// 当前this
var self = this;
// 未完成状态
self.status = "pending";
// resolve , reject
self.data = undefined;
self.callback = [];
function resolve(value) {
setTimeout(() => {
if (self.status != "pending") return;
self.data = value;
self.status = "resolved";
for (var i = 0; i < self.callback.length; i++) {
self.callback[i].onResolved(value);
}
});
// // 当从pedning转为resolve时 --> 成功
// if (self.status === 'pending') {
// self.data = value
// self.status = 'resolved'
// }
}
function reject(resaon) {
setTimeout(() => {
if (self.status != "pending") return;
self.data = resaon;
self.status = "rejected";
for (var i = 0; i < self.callback.length; i++) {
self.callback[i].onRejected(resaon);
}
});
// // 当从pending转为rejected时 --> 失败
// if (self.status === 'pending') {
// self.data = resaon
// self.status = 'rejected'
// }
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
/**
* resolve promise
* @param {*} promise
* @param {*} x
* @param {*} resolve
* @param {*} reject
*/
function resolverPromise(promise, x, resolve, reject) {
var then;
var thenCalledOrThrow = false;
if (promise === x) return reject(new TypeError("chend del promise"));
if ((x != null && typeof x === "function") || typeof x === "object") {
try {
x.then = then;
if (typeof then === "function") {
// 如果 resolvePromise 以值 y 为参数被调用,则运行 [[Resolve]](promise, y)
then.call(
x,
function rs(y) {
if (thenCalledOrThrow) return;
thenCalledOrThrow = true;
resolverPromise(promise, y, resolve, reject);
},
function rj(r) {
// 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise
if (thenCalledOrThrow) return;
thenCalledOrThrow = true;
return reject(r);
}
);
} else {
reject(x);
}
} catch (e) {
if (thenCalledOrThrow) return;
thenCalledOrThrow = true;
return reject(e);
}
} else {
resolve();
}
}
then
实现
MyPromise.prototype.then = function(onResolved, onRejected) {
// 性能优化
onResolved =
typeof onResolved === "function"
? onResolved
: function(value) {
return value;
};
onRejected =
typeof onRejected === "function"
? onRejected
: function(resaon) {
return resaon;
};
// 保存 this
var self = this;
var promise2;
// 当前状态为 resolved
if (self.status === "resolved") {
return (promise2 = new Promise(function(resolve, reject) {
setTimeout(function() {
try {
var x = onResolved(self.data);
resolverPromise(promise2, x, resolve, reject);
} catch (e) {
return reject(e);
}
});
}));
}
// 当状态改变为 rejected
if (self.status === "rejected") {
return (promise2 = new Promise(function(resolve, reject) {
setTimeout(function() {
try {
var x = onRejected(self.data);
resolverPromise(promise2, x, resolve, reject);
} catch (e) {
return reject(e);
}
});
}));
}
// 当前状态 pending
if (self.status === "pending") {
return (promise2 = new Promise(function(resolve, reject) {
self.callback.push({
onResolved: function(value) {
try {
var x = onResolved(self.data);
resolverPromise(promise2, x, resolve, reject);
} catch (e) {
return reject(e);
}
},
onRejected: function(resaon) {
try {
var x = onRejected(self.data);
resolverPromise(promise2, x, resolve, reject);
} catch (e) {
return reject(e);
}
}
});
}));
}
};
测试
var p = new MyPromise(function(resolve, reject) {
resolve(1);
});
p.then(function (x) {
console.log(x)
})
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于