82.源码实现系列-promise
Opened this issue · 0 comments
webVueBlog commented
// es6 实现
class Mypromise {
constructor(fn) {
this.state = "pending";
this.successFun = [];
this.failFun = [];
let resolve = val => {
if (this.state !== "pending") return;
this.state = "success";
setTimeout(() => {
this.successFun.forEach(item => item.call(this, val));
});
}
let reject = err => {
if (this.state !== "pending") return;
this.state = "fail";
setTimeout(() => {
this.failFun.forEach(item => item.call(this, err));
});
}
try {
fn(resolve, reject);
} catch (error) {
reject(error)
}
}
// 实例方法 then
then(resolveCallback, rejectCallback) {
resolveCallback =
typeof resolveCallback !== "function" ? v => v : resolveCallback;
rejectCallback =
typeof rejectCallback !== "function" ? err => { throw err } : rejectCallback;
return new Mypromise((resolve, reject) => {
this.successFun.push(val => {
try {
let x = resolveCallback(val);
x instanceof Mypromise ? x.then(resolve, reject) : resolve(x);
} catch (error) {
reject(error);
}
});
this.failFun.push(val => {
try {
let x = rejectCallback(val);
x instanceof Mypromise ? x.then(resolve, reject) : reject(x);
} catch (error) {
reject(error);
}
});
})
}
// 静态方法
static all(promiseArr) {
let result = [];
return new Mypromise((resolve, reject) => {
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
res => {
result.push(res);
if (i === promiseArr.length - 1) {
resolve(result);
}
},
err => {
reject(err);
}
};
}
});
}
static rece(promiseArr) {
return new Mypromise((resolve, reject) => {
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
res => {
resolve(res);
},
err => {
reject(err);
}
);
}
});
}
}
怎么才能取消已经发起的异步呢
Promise.race()方法可以用来竞争 Promise 谁的状态先变更就返回谁
那么可以借助这个 自己构造一个 Promise 来实现
function wrap(pro) {
let obj = {};
let p1 = new Promise((resolve, reject) => {
obj.resolve = resolve;
obj.reject = reject;
});
obj.promise = Promise.race([p1, pro]);
return obj;
}
let testPro = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(123);
}, 1000);
});
let wrapPro = wrap(testPro);
wrapPro.promise.then(res => {
console.log(res);
});
wrapPro.resolve("被拦截了“);