在节点中按特定顺序调用模块

Call to modules in specific order in node

本文关键字:顺序调用 模块 节点      更新时间:2023-09-26

我使用了下面的代码来调用两个模块,但是调用操作是在验证文件之前调用的(我在调试中看到的)。我该怎么验证validateFileappHandler.invokeAction之前呢?我应该用承诺吗?

var validator = require('../uti/valid').validateFile();
var appHandler = require('../contr/Handler');
appHandler.invokeAction(req, res);

更新

这是验证文件代码

var called = false;
var glob = require('glob'),
    fs = require('fs');
module.exports = {
    validateFile: function () {
        glob("myfolder/*.json", function (err, files) {
            var stack = [];
            files.forEach(function (file) {
                fs.readFile(file, 'utf8', function (err, data) { // Read each file
                    if (err) {
                        console.log("cannot read the file", err);
                    }
                    var obj = JSON.parse(data);
                    obj.action.forEach(function (crud) {
                        for (var k in crud) {
                            if (_inArray(crud[k].path, stack)) {
                                console.log("duplicate founded!" + crud[k].path);
                                break;
                            }
                            stack.push(crud[k].path);
                        }
                    })
                });
            });
        });
    }
};

因为globfs.readFile是异步函数和appHandler。

从磁盘i/o时调用invokeAction。

Promise是解决这个问题的一个很好的解决方案,但是老式的回调也可以完成这个工作。

validator.validateFile().then(function() {
  appHandler.invokeAction(req, res);
});

and for validate

var Promise = require("bluebird"), // not required if you are using iojs or running node with `--harmony`
    glob = require('mz/glob'),
    fs = require('mz/fs');
module.exports = {
  validateFile: function () {
    return glob("myfolder/*.json").then(function(files) {
      return Promise.all(files.map(function(file) {
        // will return an array of promises, if any of them
        // is rejected, validateFile promise will be rejected
        return fs.readFile(file).then(function (content) {
          // throw new Error(''); if content is not valid
        });
      }));
    })
  }
};

如果你想使用承诺mz可以帮助:)

由于fs.fileReadasync,您应该将想要在validateFile之后执行的代码放入callback

原点可以是:

var validator = require('../uti/valid').validateFile();
var appHandler = require('../contr/Handler');
// create a new function that when execute, will call appHandler.invokeAction with req and res given to its arguments.
validator.validateFile(appHandler.invokeAction.bind(null, req, res));

验证器部分应该是:

var called = false;
var glob = require('glob'),
    fs = require('fs');
module.exports = {
    validateFile: function (callback) {
        glob("myfolder/*.json", function (err, files) {
            var stack = [];
            // Use it to decide whether all files processed or not.
            var filesToLoad = files.length;
            files.forEach(function (file) {
                fs.readFile(file, 'utf8', function (err, data) { // Read each file
                    --filesToLoad;
                    if (err) {
                        console.log("cannot read the file", err);
                        // If the invoke action doesn't depend on the result. You may want to call it here too.
                    }
                    var obj = JSON.parse(data);
                    obj.action.forEach(function (crud) {
                        for (var k in crud) {
                            if (_inArray(crud[k].path, stack)) {
                                console.log("duplicate founded!" + crud[k].path);
                                break;
                            }
                            stack.push(crud[k].path);
                        }
                    })
                    // Only called the callback after all files processed.
                    if (filesToLoad === 0) {
                      callback();
                    }
                });
            });
        });
    }
};

编辑:感谢Bergi的提醒,文件是一个数组,当所有文件都被处理时,你必须调用回调,所以我们必须进一步使用一个变量来决定有多少文件尚未处理。