摊牌了, 源码没看懂. 有个地方想请教, 例子:
function* watchAndDo() {
const channel = yield actionChannel('TEST');
while (true) {
const payload = yield take(channel);
yield call(Api, payload);
}
}
这个例子中, 假如一起来了 10 个 TEST
, 则会一个一个执行. 那么这里 channel 是如何做到等待循环里的 block 结束再派发下一个动作的?
目前了解到: 创建 channel 后, dispatch 的消息会加入到 buffer 中, buffer 是一个数组.
1
FaiChou OP 明白了:
|
2
FaiChou OP function take(cb) {
if (closed && buffer.isEmpty()) { cb(END) } else if (!buffer.isEmpty()) { cb(buffer.take()) } else { takers.push(cb) cb.cancel = () => remove(takers, cb) } } 上面是 channel.js 里的代码, 首先 dispatch() 或者 put() 会将消息放到 buffer 中, 当 buffer 为空, 则还没有任何消息到来, 这时候 take(channel) 或者 take('MESSAGE') 会存到 takers 中, 在下次消息到的时候, 取出来一个来执行: function put(input) { if (closed) { return } if (!takers.length) { return buffer.put(input) } const cb = takers[0] takers.splice(0, 1) cb(input) } 如果阻塞时候 buffer 来了很多消息, 后来阻塞结束(比如例子中 while 的新一轮循环), 判断 `!buffer.isEmpty()` 会直接从 buffer 中取出一条消息来执行 cb(buffer.take()) |