关于nextTick的一点问题

最近几天在拿node搞graphql,用了dataloader来解决n+1问题。写loader的时候把loader放到了全局,当时内心就烦嘀咕,要是两个请求一块儿打过来,dataloader返回的数据会不会混淆? 好比如下这种状况:node

const pageLoader = new DataLoader(async (ids: string[]) => {
       return controller.getPages(ids);
    });
复制代码

假如两个请求的id有重合,一个ids=[1,2], 另一个ids=[2,3],若是dataloader把ids合并成[1,2,3]去请求,那返回的结果咋办?git

搞数据试了几回,发现dataloader会在第一个请求完成以后再去load第二个请求,并不存在我上面脑补的状况。 那问题又来了,dataloader咋搞的?github

DataLoader

翻了下dataloader的源码,在调用loader.load(id)的时候,会作两件事:promise

  1. 生成一个promise,合着id一块儿放到queue里。
  2. 若是是第一个key,那还要启一个任务来收集queue里的id
this._queue.push({ key, resolve, reject });
      // Determine if a dispatch of this queue should be scheduled.
      // A single dispatch should be scheduled per queue at the time when the
      // queue changes from "empty" to "full".
      if (this._queue.length === 1) {
        if (shouldBatch) {
          // If batching, schedule a task to dispatch the queue.
          enqueuePostPromiseJob(() => dispatchQueue(this));
        } else {
          // Otherwise dispatch the (queue of one) immediately.
          dispatchQueue(this);
        }
      }
      
var enqueuePostPromiseJob =
  typeof process === 'object' && typeof process.nextTick === 'function' ?
    function (fn) {
      if (!resolvedPromise) {
        resolvedPromise = Promise.resolve();
      }
      resolvedPromise.then(() => process.nextTick(fn));  // 关键, 任务被放到nextTick来执行了
    } :
    setImmediate || setTimeout;
复制代码

能够看到,收集queue里id的任务被放到nextTick里面来执行了。 也就是说,在nextTick回调执行以前load的id会被放到queue里做为一个id集合来处理,而node在处理下一个请求以前,就调用了nextTick的回调。因此 两个请求的id是不会混合的。。浏览器

但问题又来了,两个request的回调函数应当是放在事件循环的Poll Phase里面的,在处理完这个phase的队列以前,nextTick为何会被调用?bash

nextTick

翻了n多篇文章,大概讲的都是node维护了一个nextTickQueue,libuv在每一个phase即将结束,要进入下个phase以前,会检查nextTickQueue里的回调并执行。async

而后看到了这篇文章,讲node 11.0以后, 为了和浏览器一致,在macrotask执行完以后都会去执行microtask。 这个理论说得通,但问题是我用的是node 8,因此应该不是由于这个缘由。ide

最后去提了一个issue,大神给的解答大概就是说nexttick和eventloop压根儿不搭嘎,eventloop每次跑完一个handler都会跑nexttick。 大概就这样吧,也不想深究了,毕竟node 11之后,感受已经彻底能够把nexttick看成一个microtask来看了。函数

参考文献

You really hate NodeJS! Here’s why…oop

相关文章
相关标签/搜索