实现promise

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+规范的实现可不止这么简单。可以参照我的另一个博客。


为了达到比较棒的学习效果,我会减少额外的代码,比如排错类型的代码,比如判断类型什么的。

猜你喜欢

转载自www.cnblogs.com/sowhite/p/8946561.html