代码之家  ›  专栏  ›  技术社区  ›  cjl750

将延迟的函数结果返回到下一个带有Gulp tap的Gulp管道

  •  0
  • cjl750  · 技术社区  · 7 年前

    我正在创建一个简单的静态站点,在开发过程中,我使用车把.js并进行一些API调用来填充handlebar模板。但是对于产品,我想将所有模板预编译成静态HTML。

    gulp.task('compileHtml', () => {
      return gulp
        .src('index.html')
        .pipe(someThing())
        .pipe(anotherThing())
        .pipe(compileTemplates())
        .pipe(someOtherThing())
        .pipe(gulp.dest('build'));
    });
    

    compileTemplates 函数,我正在使用 gulp-tap jsdom 基本上用相关的脚本来运行文件,进行API调用并填充handlebar模板,然后删除这些脚本并将编译好的HTML发送回下一个管道。但我很难推迟到 jsdom 有足够的时间运行所有脚本。

    const compileTemplates = file => {
      return tap(file => {
        const dom = new JSDOM(file.contents,
          {
            runScripts: 'dangerously',
            resources: 'usable',
            beforeParse(window) {
              window.fetch = require('node-fetch');
            },
          },
        );
        const document = dom.window.document;
        const script = document.querySelector('script[src$="handlebars.min.js"]');
    
        // dom.serialize() still contains my uncompiled templates at this point
        setTimeout(() => {
          script.remove();
          file.contents = Buffer.from(dom.serialize()); // this is what I want to return from this function
        }, 2500);
      });
    };
    

    我知道我可能需要用承诺寄回去 file.contents 当它准备好了,但我不擅长承诺或吞咽。

    我试着回复一个在超时时间内解决的承诺,但我最终得到了 TypeError: dest.on is not a function 因为下一个管道 file 不是承诺。

    我如何重构以延迟发回我的文件 到下一个管道或从该函数发回一个承诺,然后将该承诺解析到新管道 文件 在我的 compileHtml 任务?

    我用的是大口4。

    0 回复  |  直到 7 年前
        1
  •  0
  •   cjl750    7 年前

    咨询后 Using setTimeout on Promise Chain ,我想出了如何解决超时后的承诺。

    const compileTemplates = file => {
      return tap(file => {
        const dom = new JSDOM(file.contents,
          {
            runScripts: 'dangerously',
            resources: 'usable',
            beforeParse(window) {
              window.fetch = require('node-fetch');
            },
          },
        );
        const document = dom.window.document;
        const script = document.querySelector('script[src$="handlebars.min.js"]');
    
        new Promise(resolve => {
          setTimeout(resolve, 2500);
        }).then(() => {
          script.remove();
          file.contents = Buffer.from(dom.serialize());
        });
      });
    };
    

    然而,这并没有完全解决我的问题,因为我需要等待承诺解决之前,发送新的 file gulp-tap .

    所以我用了 through2 ,而不是。

    const compileHtml = file => {
      return through2.obj(function(file, encoding, callback) {
        const dom = new JSDOM(file.contents,
          {
            runScripts: 'dangerously',
            resources: 'usable',
            beforeParse(window) {
              window.fetch = require('node-fetch');
            },
          },
        );
        const document = dom.window.document;
        const script = document.querySelector('script[src$="handlebars.min.js"]');
    
        new Promise(resolve => {
          setTimeout(resolve, 2500);
        }).then(() => {
          script.remove();
          file.contents = Buffer.from(dom.serialize());
          this.push(file);
          callback();
        });
      });
    }
    

    如果有人知道使用 大口水龙头 ,请随时发布答案!

    推荐文章