# 七.AsyncSeriesHook

  • 异步串行钩子
  • 任务一个一个执行,执行完上一个执行下一个

# 1.使用方式

let { AsyncSeriesHook } = require("tapable");
class Lesson {
  constructor() {
    this.index = 0;
    this.hooks = { arch: new AsyncSeriesHook(["name"]) };
  }
  tap() {
    this.hooks.arch.tapAsync("node", (name, cb) => {
      setTimeout(() => {
        console.log("node", name);
        cb();
      }, 1000);
    });
    this.hooks.arch.tapAsync("react", (name, cb) => {
      setTimeout(() => {
        console.log("react", name);
        cb();
      }, 1000);
    });
  }
  statr() {
    this.hooks.arch.callAsync("123", function() {
      console.log("end");
    });
  }
}
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
24
25
26
27
28
29

运行得到:

node 123
react 123
end
1
2
3

# 2.原理实现

class AsyncSeriesHook {
  //同步方法
  constructor(args) {
    //args => ['name']
    this.tasks = [];
  }
  tapAsync(name, task) {
    this.tasks.push(task);
  }
  callAsync(...args) {
    let finalCallback = args.pop();
    let index = 0;
    let next = () => {
      if (this.tasks.length === index) return finalCallback();
      let task = this.tasks[index++];
      task(...args, next);
    };
    next();
  }
}
let hook = new AsyncSeriesHook(["name"]);
let total = 0;
hook.tapAsync("node", (name, cb) => {
  setTimeout(() => {
    console.log("node", name);
    cb();
  }, 1000);
});
hook.tapAsync("react", (name, cb) => {
  setTimeout(() => {
    console.log("react", name);
    cb();
  }, 1000);
});

hook.callAsync("123", function() {
  console.log("end");
});
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
31
32
33
34
35
36
37
38

# 2.AsyncSeriesHook--AsyncPromise

# 1.使用

let { AsyncSeriesHook } = require("tapable");
class Lesson {
  constructor() {
    this.index = 0;
    this.hooks = { arch: new AsyncSeriesHook(["name"]) };
  }
  tap() {
    this.hooks.arch.tapPromise("node", name => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log("node", name);
          resolve();
        }, 1000);
      });
    });
    this.hooks.arch.tapPromise("react", name => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log("react", name);
          resolve();
        }, 1000);
      });
    });
  }
  statr() {
    this.hooks.arch.promise("123").then(function() {
      console.log("end");
    });
  }
}
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
24
25
26
27
28
29
30
31
32
33

# 2.原理

class AsyncSeriesHook {
  //同步方法
  constructor(args) {
    //args => ['name']
    this.tasks = [];
  }
  tapPromise(name, task) {
    this.tasks.push(task);
  }
  promise(...args) {
    let [first, ...others] = this.tasks;
    return others.reduce((p, n) => {
      return p.then(() => n(...args));
    }, first(...args));
    first(...args);
  }
}
let hook = new AsyncSeriesHook(["name"]);
let total = 0;
hook.tapPromise("node", name => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("node", name);
      resolve();
    }, 1000);
  });
});
hook.tapPromise("react", name => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("react", name);
      resolve();
    }, 1000);
  });
});

hook.promise("123").then(function() {
  console.log("end");
});
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
31
32
33
34
35
36
37
38
39