zoukankan      html  css  js  c++  java
  • webpack4.X之tapable实例对象AsyncParallelHook源码

    模拟手写AsyncParallelHook源码部分。

    let Hook = require('./Hook.js')
    
    class HookCodeFactory {
      args({ after, before } = {}) {
        let allArgs = this.options.args
        if (before) allArgs = [before].concat(allArgs)
        if (after) allArgs = allArgs.concat(after)
        return allArgs.join(',')  // ["name", "age"]===> name, age
      }
      head() {
        return `"use strict";var _context;var _x = this._x;`
      }
      content() {
        let code = `var _counter = ${this.options.taps.length};var _done = (function () {
          _callback();
        });`
        for (var i = 0; i < this.options.taps.length; i++) {
          code += `var _fn${i} = _x[${i}];_fn${i}(name, age, (function () {
            if (--_counter === 0) _done();
          }));`
        }
        return code
      }
      setup(instance, options) {  // 先准备后续需要使用到的数据
        this.options = options  // 这里的操作在源码中是通过 init 方法实现,而我们当前是直接挂在了 this 身上
        instance._x = options.taps.map(o => o.fn)   // this._x = [f1, f2, ....]
      }
      create() { // 核心就是创建一段可执行的代码体然后返回
        let fn
        // fn = new Function("name, age", "var _x = this._x, var _fn0 = _x[0]; _fn0(name, age);")
        fn = new Function(
          this.args({ after: '_callback' }),
          this.head() + this.content()
        )
        return fn
      }
    }
    
    let factory = new HookCodeFactory()
    
    class AsyncParallelHook extends Hook {
      constructor(args) {
        super(args)
      }
    
      compile(options) {  // {taps: [{}, {}], args: [name, age]}
        factory.setup(this, options)
        return factory.create(options)
      }
    }
    
    module.exports = AsyncParallelHook
    class Hook {
      constructor(args = []) {
        this.args = args
        this.taps = []  // 将来用于存放组装好的 {}
        this._x = undefined  // 将来在代码工厂函数中会给 _x = [f1, f2, f3....]
      }
    
      tap(options, fn) {
        if (typeof options === 'string') {
          options = { name: options }
        }
        options = Object.assign({ fn }, options)  // { fn:... name:fn1 }
    
        // 调用以下方法将组装好的 options 添加至 []
        this._insert(options)
      }
    
      tapAsync(options, fn) {
        if (typeof options === 'string') {
          options = { name: options }
        }
        options = Object.assign({ fn }, options)  // { fn:... name:fn1 }
    
        // 调用以下方法将组装好的 options 添加至 []
        this._insert(options)
      }
    
      _insert(options) {
        this.taps[this.taps.length] = options
      }
    
      call(...args) {
        // 01 创建将来要具体执行的函数代码结构
        let callFn = this._createCall()
        // 02 调用上述的函数(args传入进去)
        return callFn.apply(this, args)
      }
    
      callAsync(...args) {
        let callFn = this._createCall()
        return callFn.apply(this, args)
      }
    
      _createCall() {
        return this.compile({
          taps: this.taps,
          args: this.args
        })
      }
    }
    
    module.exports = Hook
     const SyncHook=require('./AsyncParallelHook.js')
    //const { AsyncParallelHook } =require('tapable')
    let hook=new AsyncParallelHook(["name","age"])
    
    hook.tapAsync('fn1',function(name,age,callback){
        console.log('fn1--->',name,age)
        callback()
    })
    
    hook.tapAsync('fn2',function(name,age,callback){
        console.log('fn2--->',name,age)
        callback()
    })
    
    hook.callAsync('lw',18,function(){
        console.log('end...')
    })
    ---感谢阅读,o(* ̄︶ ̄*)o开心每一天!
  • 相关阅读:
    Building a Space Station POJ
    Networking POJ
    POJ 1251 Jungle Roads
    CodeForces
    CodeForces
    kuangbin专题 专题一 简单搜索 POJ 1426 Find The Multiple
    The Preliminary Contest for ICPC Asia Shenyang 2019 F. Honk's pool
    The Preliminary Contest for ICPC Asia Shenyang 2019 H. Texas hold'em Poker
    The Preliminary Contest for ICPC Asia Xuzhou 2019 E. XKC's basketball team
    robotparser (File Formats) – Python 中文开发手册
  • 原文地址:https://www.cnblogs.com/websiteblogs/p/14466685.html
Copyright © 2011-2022 走看看