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开心每一天!
  • 相关阅读:
    WTL for Visual Studio 2012 配置详解
    自己动手让Visual Studio的Win32向导支持生成对话框程序
    改造联想Y480的快捷键(跨进程替换窗口过程(子类化)的实现——远程线程注入)
    Visual Studio 2012 Ultimate RTM 体验(附下载地址和KEY)
    VC++实现获取文件占用空间大小的两种方法(非文件大小)
    为Visual Studio添加默认INCLUDE包含路径一劳永逸的方法(更新)
    Winsdows 8 环境下搭建Windows Phone 开发环境
    Linq to Visual Tree可视化树的类Linq查询扩展API(译)
    检测元素是否在界面可显示区域
    Debug the Metro Style App:Registration of the app failed
  • 原文地址:https://www.cnblogs.com/websiteblogs/p/14466685.html
Copyright © 2011-2022 走看看