koa-compose源码疑惑求助
发布于 3 小时前 作者 huhu2356 69 次浏览 来自 问答

提取了部分koa-compose代码,并作了修改,如下:

class koa {
  constructor() {
    this.middleware = [];
  }

  listen() {
    const cb = this.compose(this.middleware);
    const x = cb();
    console.log(x);
  }

  use(fn) {
    this.middleware.push(fn);
  }

  compose(middleware) {
    return function () {
      let index = -1;     
      return dispatch(0);

      function dispatch(i) {
        if (i <= index) return Promise.reject(new Error('next() called multiple times'));
        index = i;
        let fn = middleware[i];
        if (!fn) return Promise.resolve();
        try {
          return Promise.resolve(fn(function next() {
            return dispatch(i + 1);
          }));
        } catch (error) {
          return Promise.reject(error);
        }
      }
    };
  }
}

const ko = new koa();

ko.use(async next => {
  console.log(1);
  await next();
  console.log(5);
});

ko.listen();

output:

1
Promise { pending }
5

问题: 1、 为什么输出是1 promise { pending } 5 , 而不是1 5 promise 2、

          return Promise.resolve(fn(function next() {
            return dispatch(i + 1);
          }));

能不能改为

          return fn(function next() {
            return dispatch(i + 1);
          });

根据MDN : The Promise.resolve(value) method returns a Promise object that is resolved with the given value. if the value was a promise, that object becomes the result of the call to Promise.resolve; 那么既然这个fn是async函数,且async函数返回的是promise.resovle(),那岂不是可以去掉外面这一层Promise.resolve?

大佬们,need help help ~~~

2 回复

第一个问题

(async () => {
	await Promise.resolve(1)
	console.log('2')
})()
console.log('1')

如果你明白上面执行顺序就不会有疑问了, 有疑问看 async 实现以及知道 promise.then 函数是 异步执行的

第二个问题 是可以去掉的, 但 koa 源码是 fn(ctx).then().catch() 你想想你要是函数且不返回 next() 岂不是 boom 了…

回到顶部