自定义封装实现Promise
//原promise对比
// let p = new Promise((resolve, reject) => {
//var ids = setTimeout(()=>{
//resolve("success");
// reject("false");
// },1000)
// clearTimeout(ids);
// reject("false");
// throw("ERROR")
// })
// console.log(p);
// let x = new Promise(() => {});
// console.log(x);
// let result = p.then(value => {
//console.log(value);
// throw("ERROR2")
// }, reason => {
// console.log(reason);
// return new Promise((resolve, reject) => {
//throw("ERROR2")
// })
// }).then(value => {
//console.log(value,"xxx");
// }, reason => {
//console.log(reason,"yyy");
// return new Promise((resolve, reject) => {
//throw("ERROR1")
// })
// })// p.then(value => {
//alert(value)
// }, reason => {
//console.log(reason);
// })
// console.log(result,"sasas");
// console.log(p);
let p = new Promise((resolve, reject) => {
var ids = setTimeout(() => {
// resolve("success");
// throw "false"
reject("false")
}, 1000)
})
p.then(() => {
console.log(111);
}).then(() => {
console.log(222);
}).then(() => {
console.log(333);
}).catch((error) => {
console.log(error);
})let x = Promise.resolve("aaa")
console.log(x);
let y = Promise.resolve(new Promise((resolve, reject) => {reject("false")}))
console.log(y);
//Promise.jsfunction Promise(executer){
this["[[PromiseState]]"] = "pending";
this.callback = {};
let self = this;
function resolve(data){
if(self["[[PromiseState]]"] !== "pending") return;
self["[[PromiseState]]"] = "resolved";
self["[[PromiseResult]]"] = data;
//if(self.callback.onResolved) self.callback.onResolved(data);
//self.callbacks.forEach(item => item.onResolved(data));
setTimeout(()=>{
self.callbacks.forEach(item => item.onResolved(data));
})
}function reject(data){
if(self["[[PromiseState]]"] !== "pending") return;
self["[[PromiseState]]"] = "rejected";
self["[[PromiseResult]]"] = data;
//if(self.callback.onResolved) self.callback.onRejected(data);
//self.callbacks.forEach(item => item.onRejected(data));
setTimeout(()=>{
self.callbacks.forEach(item => item.onRejected(data));
})
}try {
executer(resolve,reject);
} catch (error) {
reject(error);
}
}Promise.prototype.then = function(onResolved,onRejected){
/*
this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callback = {onResolved,onRejected};
*/
/*
this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callbacks.push({onResolved,onRejected});
*/
/*
return new Promise((resolve,reject) => {
let result = this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callbacks.push({onResolved,onRejected});
result instanceof Promise ? result.then(v => resolve(v),r => reject(r)) : resolve(result);
})
*/
/*
return new Promise((resolve,reject) => {
try {
let result = this["[[PromiseState]]"] === "resolved" ? onResolved(this["[[PromiseResult]]"]) : this["[[PromiseState]]"] === "rejected" ? onRejected(this["[[PromiseResult]]"]) : this.callbacks.push({onResolved,onRejected});
result instanceof Promise ? result.then(v => resolve(v),r => reject(r)) : resolve(result);
} catch (error) {
reject(error);
}
})
*/
/*
return new Promise((resolve,reject) => {
if(this["[[PromiseState]]"] === "resolved"){
try {
let result = onResolved(this["[[PromiseResult]]"]);
if(result instanceof Promise){
result.then(v => resolve(v),r => reject(r))
}else{
resolve(result)
}
} catch (error) {
reject(error);
}
}
if(this["[[PromiseState]]"] === "rejected"){
onRejected(this["[[PromiseResult]]"])
}
if(this["[[PromiseState]]"] === "pending"){
this.callbacks.push({onResolved,onRejected})
}
})
*/
/*
return new Promise((resolve,reject) => {
let self = this;
if(self["[[PromiseState]]"] === "resolved"){
try {
let result = onResolved(self["[[PromiseResult]]"]);
if(result instanceof Promise){
result.then(v => resolve(v),r => reject(r))
}else{
resolve(result)
}
} catch (error) {
reject(error);
}
}
if(self["[[PromiseState]]"] === "rejected"){
try {
let result = onRejected(self["[[PromiseResult]]"]);
if(result instanceof Promise){
result.then(v => resolve(v),r => reject(r))
}else{
resolve(result)
}
} catch (error) {
reject(error);
}
}
if(self["[[PromiseState]]"] === "pending"){
self.callbacks.push({onResolved:function(){
try {
let result = onResolved(self["[[PromiseResult]]"]);
if(result instanceof Promise){
result.then(v => resolve(v),r => reject(r))
}else{
resolve(result)
}
} catch (error) {
reject(error);
}
},onRejected:function(){
try {
let result = onRejected(self["[[PromiseResult]]"]);
if(result instanceof Promise){
result.then(v => resolve(v),r => reject(r))
}else{
resolve(result)
}
} catch (error) {
reject(error);
}
}})
}
})
*/
return new Promise((resolve,reject) => {
let self = this;
if(typeof onResolved !== "function"){
onResolved = value => value;
}
if(typeof onRejected !== "function"){
onRejected = reason => {
throw reason;
}
}
function callback(excute){
try {
let result = excute(self["[[PromiseResult]]"]);
if(result instanceof Promise){
result.then(v => resolve(v),r => reject(r))
}else{
resolve(result)
}
} catch (error) {
reject(error);
}
}
if(this["[[PromiseState]]"] === "resolved"){
//callback(onResolved)
setTimeout(()=>{
callback(onResolved)
})
}
if(this["[[PromiseState]]"] === "rejected"){
//callback(onRejected)
setTimeout(()=>{
callback(onRejected)
})
}
if(this["[[PromiseState]]"] === "pending"){
this.callbacks.push({onResolved:function(){
callback(onResolved)
},onRejected:function(){
callback(onRejected)
}})
}
})
}Promise.prototype.catch = function(onRejected){
return this.then(undefined,onRejected);
}Promise.resolve = function(value){
return new Promise((resolve,reject) => {
value instanceof Promise ? value.then(v => resolve(v),r => reject(r)) : resolve(value);
})
}Promise.reject = function(reason){
return new Promise((resolve,reject) => {
reject(reason);
})
}Promise.all = function(promises){
return new Promise((resolve,reject) => {
let resarr = [];
let count = 0;
promises.forEach((item,index) => {
item.then(v => {
count++;
resarr[index] = v;
if(count === promises.length) resolve(resarr);
},r => {
reject(r);
})
})
})
}Promise.race = function(promises){
return new Promise((resolve,reject) => {
promises.forEach(item => {
item.then(v => {
resolve(v);
},r => {
reject(r);
})
})
})
}
【js日记|自定义封装实现Promise】拆分解析
//executer 执行函数参数,传入Promise对象的是一个回调函数
//resolve和reject executer()函数的参数是两个函数参数//Promise.prototype.then 实例化Promise对象后仍旧可以调用then属性指向函数代表then属性是原型链上原型对象属性//self = this 储存this指向,防止丢失
//self.PromiseState Promise对象的状态改变
//self["[[PromiseResult]]"] = data 返回结果为传入参数//if(self["[[PromiseState]]"] !== "pending") returnPromise对象状态只能改变一次//try catchPromise状态改变的三种方式:resolve、reject、throw,后两者返回状态皆为rejected//三目运算符调用:三种状态的处理
//this.callback = {onResolved,onRejected} 处理异步,存在异步时,将then的参数储存在对象上,在状态改变时进行调用
//his.callback => his.callbacks //考虑到多次调用Promise.then也可执行,若callback为对象,则多次调用会产生覆盖而只执行最后一个then//return new Promise() Promise对象then方法执行后返回一个Promise对象
//声明result变量 then方法返回的值若不是Promise对象,则作为值传入resolve执行,是Promise对象则执行then方法且状态与上一个返回的Promise对象状态相同//放弃三目运算符的原因:存在bug,异步执行Promise对象状态为挂起时,变量result接收undefined,继续向后执行,与预期效果相悖,先换回if else,后期优化再做考虑//4个try cache 暂未考虑代码冗余问题,此处处理Promise对象异步执行结束后状态未按照原Promise改变仍旧为pending的问题//function callback 函数封装解决代码冗余//typeof...Promise.then可以值传递//Promise.prototype.catch 捕获异常且可以异常穿透//Promise.resolve 实例化对象不具有的resolve属性,快速创建Promise对象//Promise.reject 实例化对象不具有的reject属性,快速创建Promise对象//Promise.all 数组中元素状态全为resolve时,状态为resolved,返回结果为数组元素返回结果组成的数组,否则状态为rejected。返回结果为第一个状态改变为rejected的数组元素//Promise.race 数组中第一个元素的状态和返回结果决定了该方法的状态与返回结果//setTimeout(()=>{}) then方法为异步调用
封装为类
class Promise{
constructor(executer){
this["[[PromiseState]]"] = "pending";
this.callbacks = [];
let self = this;
function resolve(data){
if(self["[[PromiseState]]"] !== "pending") return;
self["[[PromiseState]]"] = "resolved";
self["[[PromiseResult]]"] = data;
setTimeout(()=>{
self.callbacks.forEach(item => item.onResolved(data));
})
}function reject(data){
if(self["[[PromiseState]]"] !== "pending") return;
self["[[PromiseState]]"] = "rejected";
self["[[PromiseResult]]"] = data;
setTimeout(()=>{
self.callbacks.forEach(item => item.onRejected(data));
})
}try {
executer(resolve,reject);
} catch (error) {
reject(error);
}
}then(onResolved,onRejected){
let self = this;
if(typeof onResolved !== "function"){
onResolved = value => value;
}
if(typeof onRejected !== "function"){
onRejected = reason => {
throw reason;
}
}
return new Promise((resolve,reject) => {
function callback(excute){
try {
let result = excute(self["[[PromiseResult]]"]);
if(result instanceof Promise){
result.then(v => resolve(v),r => reject(r))
}else{
resolve(result)
}
} catch (error) {
reject(error);
}
}
if(this["[[PromiseState]]"] === "resolved"){
setTimeout(()=>{
callback(onResolved)
})
}
if(this["[[PromiseState]]"] === "rejected"){
setTimeout(()=>{
callback(onRejected)
})
}
if(this["[[PromiseState]]"] === "pending"){
this.callbacks.push({onResolved:function(){
callback(onResolved)
},onRejected:function(){
callback(onRejected)
}})
}
})
}catch(onRejected){
return this.then(undefined,onRejected);
}static resolve(value){
return new Promise((resolve,reject) => {
value instanceof Promise ? value.then(v => resolve(v),r => reject(r)) : resolve(value);
})
}static reject(reason){
return new Promise((resolve,reject) => {
reject(reason);
})
}static all(promises){
return new Promise((resolve,reject) => {
let resarr = [];
let count = 0;
promises.forEach((item,index) => {
item.then(v => {
count++;
resarr[index] = v;
if(count === promises.length) resolve(resarr);
},r => {
reject(r);
})
})
})
}static race(promises){
return new Promise((resolve,reject) => {
promises.forEach(item => {
item.then(v => {
resolve(v);
},r => {
reject(r);
})
})
})
}}
推荐阅读
- 关于three.js修改直线页面没显示问题
- 操作系统|[译]从内部了解现代浏览器(1)
- web网页模板|如此优秀的JS轮播图,写完老师都沉默了
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- vue.js|vue中使用axios封装成request使用
- JavaScript|JavaScript: BOM对象 和 DOM 对象的增删改查
- JavaScript|JavaScript — 初识数组、数组字面量和方法、forEach、数组的遍历
- JavaScript|JavaScript — call()和apply()、Date对象、Math、包装类、字符串的方法
- JavaScript|JavaScript之DOM增删改查(重点)