# 三.SyncWaterfallHook

前言

同步执行全部直到没有返回值,队列顺序

  • SyncWaterfallHook 表示如果上一个回调函数的结果不为 undefined,则可以作为下一个回调函数的第一个参数
  • 回调函数的参数来自上一个函数的结果
  • 调用 call 传入的第一个参数,会被上一个函数的非 undefined 结果替换
  • 当回调函数返回非 undefiend 不会停止回调栈的调用

# 1.使用方式

let { SyncWaterfallHook } = require("tapable")

class Lesson {
  constructor() {
    this.hooks = { arch: new SyncWaterfallHook(["name"]) }
  }
  tap() {
    //注册监听函数
    this.hooks.arch.tap("node", function (name) {
      console.log("node", name)
      return "stop"
    })
    this.hooks.arch.tap("react", function (name) {
      console.log("react", name)
    })
  }
  statr() {
    this.hooks.arch.call("123")
  }
}
let l = new Lesson()
l.tap() //注册这两个事件
l.statr() //启动钩子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

运行得到:

node 123
react stop
1
2

# 2.原理实现

class SyncWaterfallHook {
  //同步方法
  constructor(args) {
    //args => ['name']
    this.tasks = []
  }
  tap(name, task) {
    this.tasks.push(task)
  }
  call(...args) {
    let [first, ...others] = this.tasks
    let ret = first(...args)
    others.reduce((a, b) => {
      return b(a)
    }, ret)
  }
}
let hook = new SyncWaterfallHook(["name"])
hook.tap("node", function (name) {
  console.log("node", name)
  return "node"
})
hook.tap("react", function (name) {
  console.log("react", name)
  return "react"
})
hook.tap("webpack", function (name) {
  console.log("webpack", name)
})
hook.call("123")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30