promise的规范其实种类很多,我们最常用的是promise/A+
首先我们实现一个简单的promise,这个promise类似于express的路由处理
express的路由处理以next的方式一层一层的进入, 直到不再next。这个很像promise呐,也是比较懒,没有去看源码,但试着实现一个那种异步,会发现其实蛮简单的。
ok,废话少说,先搞一个
需求
1. promise拥有then和catch方法
2. promise出错时调用catch,有两种错误,主动跑错可以用next(err)
3. promise的第一个参数为function, 第一个参数为next,其他参数可以传递到下一步。
然后我们要实现的功能如下
new Promise(next => { setTimeout(() => { console.log(1); next(null, 2); }, 1000); }) .then((next, arg) => { setTimeout(() => { console.log(arg); next(); }, 1000); }) .then((next, arg) => { setTimeout(() => { console.log(arg); next(); }, 1000); }) .catch(err => console.error(err));
实现
首先我们实现then和catch方法
我们建立一个回调队列和一个出错回调1
1)then里的东西都会被推进去
2)catch会去替换默认的回调方法
3)next函数会执行resovleCallbacks里的下一个方法
function Promise(execute) { let resolveCallbacks = []; let rejectCallbacks = err => console.error(err); this.then = fn => { resolveCallbacks.push(fn); return this; }; this.catch = fn => { rejectCallback = fn; return this; }; execute(next); function next() { const nextCallback = resolveCallbacks.shift(); nextCallback && nextCallback(next); } }
为了捕捉错误
try { execute(next); } catch (err) { rejectCallback(err); }
我们添加如上的错误捕捉机制
假如果主动跑错就用next(err)
没有出错的话就next(null, arg1, arg2)这样传参
所以我们修改next方法
function next(...args) { if(args[0]){ return rejectCallback(args[0]); }else{ const nextCallback = resolveCallbacks.shift(); try { nextCallback && nextCallback(next, ...args.slice(1)); } catch (err) { rejectCallback(err); } } }
至此就实现完成了,很简单吧
game over
但事实上一个伟大的promise/A+规范的实现可不止这么简单。可以参照我的另一个博客。
为了达到比较棒的学习效果,我会减少额外的代码,比如排错类型的代码,比如判断类型什么的。