-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 10 题:简单手写实现promise #10
Comments
new PromiseM((res, rej) => { |
大神思路很清晰,不过上面代码还是有些bug |
这里不支持多层then链式调用(then中可返回新的promise进行异步流控制),不支持finally,我写了个版本,多多指教 |
对你的实现then 做了如下改动,感觉是不需要轮询的 |
附加需求:
let isThenable = x => !!(x!==undefined && x.then);
let runThenable = (func, arg) => isThenable(arg) ? arg.then(func) : func(arg);
class MyPromise{
constructor(f){
this.succ_que = [];
this.fail_que = [];
this.done = false;
this.resolve = result => {
if(this.done) return;
this.result = result;
this.done = true;
setImmediate(() => { // setImmediate to prevent children from being caught by parent
this.succ_que.forEach(cb => cb(result));
});
};
this.reject = error => {
if(this.done) return;
this.error = error;
this.done = true;
setImmediate(() => {
this.fail_que.forEach(cb => cb(error));
});
};
this.then = (succ_cb, fail_cb) => new MyPromise((next_resolve, next_reject) => {
let handle_result = v => {
try{
runThenable(next_resolve, succ_cb ? succ_cb(v) : v); // runThenable to allow succ_cb/fail_cb return a promise
} catch (e) {
next_reject(e)
}
};
let handle_error = e => {
try{
if(fail_cb)
runThenable(next_resolve, fail_cb(e)); // resume after caught by fail_cb
else
next_reject(e);
}catch (e) {
next_reject(e)
}
};
if(this.done){
this.error ? handle_error(this.error) : handle_result(this.result)
}else{
this.succ_que.push(handle_result);
this.fail_que.push(handle_error);
}
});
this.catch = fail_cb => this.then(null, fail_cb);
try{
f(this.resolve, this.reject);
}catch (e) {
this.reject(e);
}
}
}
MyPromise.resolve = x => new MyPromise(r => r(x));
MyPromise.Any = (...promises) => {
let done = 0;
return new MyPromise(r => {
promises.forEach(p => p.then(v =>{ if(!done){done++; r(v);} }));
})
};
MyPromise.All = (...promises)=>{
let count = promises.length;
let values = [];
return new MyPromise((r, f) => {
promises.forEach((p, i) =>
p.then(v => {
values[i] = v;
count --;
if(count === 0) r(values);
}, f)
)
});
};
// test:
MyPromise.resolve(1)
.then(v=> v+1)
.catch(e => console.log(`won't happen error: ${e}`))
.then(v => {console.log(`continued: ${v}`); throw new Error("throw");})
.then(v => {console.log("won't happen then");})
.catch(e => {console.log(`catched: ${e}`); return 100;})
.then(v => {console.log(`continue after catch: ${v}`); return v;})
.then(v => new MyPromise(r=> setTimeout(() => r(v+500), 3000)))
.then(v => console.log(`last: ${v}`))
;
console.log("==========="); |
有几个疑问哈... |
对于这里的 Promise then 里面 done 部分处理有点不解。 最后结果应该是 1, 3, 5, 2, 4 如果在then 里面因为是同步操作就done的话 then 的 cb 不会进入到 succ_cb中 |
The text was updated successfully, but these errors were encountered: