美文网首页
NodeJS如何用exec实现execSync的功能

NodeJS如何用exec实现execSync的功能

作者: CXYMichael | 来源:发表于2018-09-16 11:26 被阅读586次

笔者在使用gulp编译Angular项目时,由于编译服务器使用的是低版本Node JS,不支持同步执行脚本的方法execSync,导致只能使用异步加回调的方式执行,在这种情况下,如何保证异步任务顺序执行呢?官方给出的解决方案如下:

异步任务支持

任务可以异步执行,如果 fn 能做到以下其中一点:

接受一个 callback

// 在 shell 中执行一个命令
var exec = require('child_process').exec;
gulp.task('jekyll', function(cb) {
  // 编译 Jekyll
  exec('jekyll build', function(err) {
    if (err) return cb(err); // 返回 error
    cb(); // 完成 task
  });
});

返回一个 stream

gulp.task('somename', function() {
  var stream = gulp.src('client/**/*.js')
    .pipe(minify())
    .pipe(gulp.dest('build'));
  return stream;
});

返回一个 promise

var Q = require('q');

gulp.task('somename', function() {
  var deferred = Q.defer();

  // 执行异步的操作
  setTimeout(function() {
    deferred.resolve();
  }, 1);

  return deferred.promise;
});

注意: 默认的,task 将以最大的并发数执行,也就是说,gulp 会一次性运行所有的 task 并且不做任何等待。如果你想要创建一个序列化的 task 队列,并以特定的顺序执行,你需要做两件事:

给出一个提示,来告知 task 什么时候执行完毕,
并且再给出一个提示,来告知一个 task 依赖另一个 task 的完成。
对于这个例子,让我们先假定你有两个 task,"one" 和 "two",并且你希望它们按照这个顺序执行:

在 "one" 中,你加入一个提示,来告知什么时候它会完成:可以再完成时候返回一个 callback,或者返回一个 promise 或 stream,这样系统会去等待它完成。

在 "two" 中,你需要添加一个提示来告诉系统它需要依赖第一个 task 完成。

因此,这个例子的实际代码将会是这样:

var gulp = require('gulp');

// 返回一个 callback,因此系统可以知道它什么时候完成
gulp.task('one', function(cb) {
    // 做一些事 -- 异步的或者其他的
    cb(err); // 如果 err 不是 null 或 undefined,则会停止执行,且注意,这样代表执行失败了
});

// 定义一个所依赖的 task 必须在这个 task 执行之前完成
gulp.task('two', ['one'], function() {
    // 'one' 完成后
});

gulp.task('default', ['one', 'two']);

监测文件变化

假设脚本A执行编译命令,脚本B将A编译完成的文件拷贝到X目录,脚本C则将X目录下的文件打包,那么就可以使用监控文件的方式实现脚本的同步。

gulp.watch(glob[, opts, cb])

glob

类型: String or Array

一个 glob 字符串,或者一个包含多个 glob 字符串的数组,用来指定具体监控哪些文件的变动。

opts

类型: Object

传给 gaze 的参数。

cb(event)

类型: Function

每次变动需要执行的 callback。

gulp.watch('js/**/*.js', function(event) {
  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});

callback 会被传入一个名为 event 的对象。这个对象描述了所监控到的变动:

event.type

类型: String

发生的变动的类型:added, changed 或者 deleted

event.path

类型: String

触发了该事件的文件的路径。

gulp-watch

值得注意的是官方的gulp.watch不支持监听文件的创建的删除,可以使用第三方插件gulp-watch来替代。

安装
npm install --save-dev gulp-watch
使用
var gulp = require('gulp'),
    watch = require('gulp-watch');
 
gulp.task('stream', function () {
    // Endless stream mode
    return watch('css/**/*.css', { ignoreInitial: false })
        .pipe(gulp.dest('build'));
});
 
gulp.task('callback', function () {
    // Callback mode, useful if any plugin in the pipeline depends on the `end`/`flush` event
    return watch('css/**/*.css', function () {
        gulp.src('css/**/*.css')
            .pipe(gulp.dest('build'));
    });
});

合并任务脚本

如果只是执行多个批处理脚本,实际上完全可以通过合并脚本的方式实现同步,而且简化了大量代码。即便在不允许合并脚本的情况下,也可以通过把多个task合并成一个,然后在每个脚本的callback中执行下一个版本的方式实现同步执行,当然前提是每个异步方法都有回调函数:
|脚本A| ------callback----->|脚本B| ------callback----->|脚本C|

原生文件命令

gulp的task和watch命令实际上也只是对NodeJS的API的封装,那么我们可不可以使用NodeJS的原生命令实现同样的效果呢?答案当然是肯定的。
首先引用FileSystem库

var fs = require('fs');

然后以文件作为信号,A任务使用open命令创建文件,B任务定时用exists判断文件是否存在,存在时用watch命令监听文件名变化事件,文件名发生变化时执行脚本,并删除文件。完整流程如下:


文件同步流程图

相关文章

  • NodeJS如何用exec实现execSync的功能

    笔者在使用gulp编译Angular项目时,由于编译服务器使用的是低版本Node JS,不支持同步执行脚本的方法e...

  • nodejs实现发邮件

    nodejs有许许多多的功能模块,今天给大家演示如何用nodejs实现发邮件的效果,我们以QQ邮箱为例! 首先我们...

  • 简单的maven自动发布

    功能 通过maven的exec-maven-plugin实现自动发布并查看服务端日志 实现 exec-maven-...

  • Redis从入门到精通(五、Redis的事务)

    Redis通过 MULTI,EXEC,DISCARD,WATCH.UNWATCH 来实现事务功能。 Redis 事...

  • 服务端node的一些用法(初级)

    做接口 nodejs调用系统命令 NodeJS中用child_process的exec执行cd指令为什么不工作? ...

  • Redis-事物

    Redis 通过 MULTI 、 DISCARD 、 EXEC 和 WATCH 四个命令来实现事务功能, 本章首先...

  • Redis学习笔记

    一、Redis事务 Redis实现了基本的事务功能,但是不具有回滚功能。Redis通过使用 MULTI和EXEC两...

  • 第十九章 事务

    Redis通过MULTI、EXEC、WATCH等命令来实现事务功能。 事务的实现 事务从开始到结束经历以下三个阶段...

  • Redis事务

    Redis通过MULTI、EXEC、WATCH等命令来实现事务(transaction)功能。事务提供了一种将多个...

  • 命令执行之RunTime.getRuntime().exec()

    在java中,RunTime.getRuntime().exec()实现了调用服务器命令脚本来执行功能需要。 用法...

网友评论

      本文标题:NodeJS如何用exec实现execSync的功能

      本文链接:https://www.haomeiwen.com/subject/nxpxnftx.html