繁体   English   中英

如何从异步函数响应创建Node.js模块?

[英]How to create a Node.js module from Asynchronous Function response?

这个问题是关于依赖异步函数返回内容的Node模块的创建。 例如,“ src / index.js”如下:

目标

必须解析从“ src / index”实现的模块A,并且不得依赖promise或其他任何东西。它只会返回一个计算值的JSON对象。

var a = require("./src/index");
// should be resolved already.
console.log(a.APP_NAME) 

src / index.js

"use strict";
var CoreClass = require("./core-class");

var coreInstance = new CoreClass();

coreInstance.toJson(function(err, coreData) {
  if (err) {
    console.log("Error while loading " + __filename);
    console.log(err);
    return;
  }

  console.log(coreData);
  // Export the data from the core.
  module.exports = coreData;
});

src / core-class.js

在文件“ src / core-class.js”的类中定义的方法“ toJson()”的实现如下:

/**
 * @return {string} Overriding the toStrng to return the object properties.
 */
ISPCore.prototype.toJson = function toJson(callback) {
  var result = {
    // From package.json
    APP_NAME: this.appPackageJson.name.trim(),
    APP_VERSION: this.appPackageJson.version.trim(),
    APP_CONFIG_DIR: this.APP_DIR + "/config",
    APP_DOCS_DIR: this.APP_DIR + "/docs",
    APP_TESTS_DIR: this.APP_DIR + "/tests",
  };

  // TODO: Remove this when we have a registry
  if (!this.pom) {
    // Let's verify if there's a pom.xml file in the roort APP_DIR
    var _this = this;
    this.APP_POM_PATH = this.APP_DIR + "/pom.xml";

    // Check first to see if the file exists
    fs.stat(this.APP_POM_PATH, function(err, fileStats) {
      // The file does not exist, so we can continue with the current result.
      if (err) {
        return callback(null, result);
      }
      _this._loadPomXmlSettings(function pomXmlCallback(err, pomObject) {
        if (err) {
          return callback(err);
        }

        _this.pom = pomObject;
        // Update the result with the pom information
        result.POM_GROUPID = _this.pom.groupid || "undefined";
        result.POM_ARTIFACTID = _this.pom.artifactid || "undefined";
        result.POM_VERSION = _this.pom.version || "undefined";

        // Callback with the updated version.
        return callback(null, result);
      });

    });

  } else {
    result.POM_GROUPID = this.pom.groupid || "undefined";
    result.POM_ARTIFACTID = this.pom.artifactId || "undefined";
    result.POM_VERSION = this.pom.version || "undefined";

    // Return just what's been collected so far, including the pom.
    return callback(null, result);
  }
};

测试班

要求这样做并尝试使用该库只会返回一个空对象。 这是测试课...

  // describing the method to get the instance.
  describe("require(sp-core) with pom.xml", function() {

    var core = null;

    before(function(done) {
      // Copy the fixture pom.xml to the APP_DIR
      fs.writeFileSync(__dirname + "/../pom.xml", fs.readFileSync(__dirname + "/fixture/pom.xml"));
      // Load the library after the creation of the pom
      core = require("../src/");
      console.log("TEST AFTER CORE");
      console.log(core);

      done();
    });

    after(function(done) {
      // Delete the pom.xml from the path
      fs.unlinkSync(__dirname + "/../pom.xml");

      done();
    });

    it("should load the properties with pom properties", function(done) {
      expect(core).to.be.an("object");
      console.log("Loaded pom.xml metadata");
      console.log(core);
      expect(core.POM_ARTIFACTID).to.exist;
      expect(core.POM_VERSION).to.exist;

      done();
    });
  });

执行测试

但是,过一会儿,库的输出将显示在控制台中。

  SPCore with pom.xml
    require(sp-core) with pom.xml
TEST AFTER CORE
{}
Loaded pom.xml metadata
{}
      1) should load the properties with pom properties
{ APP_NAME: 'sp-core',
  APP_VERSION: '0.3.5',
  ENV: 'development',
  NODE_ENV: 'development',
  IS_PROD: false,
  APP_DIR: '/home/mdesales/dev/isp/sp-core',
  APP_CONFIG_DIR: '/home/mdesales/dev/isp/sp-core/config',
  APP_DOCS_DIR: '/home/mdesales/dev/isp/sp-core/docs',
  APP_TESTS_DIR: '/home/mdesales/dev/isp/sp-core/tests',
  POM_GROUPID: 'com.mycompany',
  POM_ARTIFACTID: 'my-service',
  POM_VERSION: '1.0.15-SNAPSHOT' }


  0 passing (142ms)
  1 failing

  1) SPCore with pom.xml require(sp-core) with pom.xml should load the properties with pom properties:
     AssertionError: expected undefined to exist

如何正确创建依赖于异步调用的模块?

我确定这是由于异步调用引起的,但我当时认为该模块不会返回{},而是要等到回调返回。

我尝试使用:

  • 异步瀑布
  • 异步(不起作用)

异步瀑布尝试

"use strict";

var async = require("async");
var CoreClass = require("./core-class");
var coreInstance = new CoreClass();

async.waterfall([
  function(cb) {
    coreInstance.toJson(cb);
  },
  function(coreData) {
    console.log(coreData);
    module.exports = coreData;
  }
]);

请帮忙!

在评论之后,我重新尝试了使用“ deasync”模块的尝试,并且成功了! 我们可以! 欺骗“ deasync”:D

可运行实例

可运行的解决方案位于http://code.runnable.com/VbCksvKBUC4xu3rd/demo-that-an-async-method-can-be-returned-before-a-module-exports-is-resolved-for-node-js -deasync-pom分析器和堆栈溢出31577688

  • 在接线盒中键入“ npm test”,然后单击“ ENTER”(始终有效)。
  • 只需单击“运行”按钮以查看代码的执行。 所有源代码均可用。 (有时容器会损坏并且测试失败)。

这是“ GOAL”模块的实现。

/** @module Default Settings */

"use strict";
var CoreClass = require("./core-class");
var merge = require("merge");
var deasync = require("deasync");

// Core properties needed.
var coreInstance = new CoreClass();
var coreProperties = coreInstance.toJson();

// Pom properties temporary support, deasync the async call
var loadPom = deasync(coreInstance.loadPomXmlSettings);
var pomObject = loadPom(coreProperties.APP_POM_PATH);

// Merge them all.
var allProperties = merge(coreProperties, pomObject);

module.exports = allProperties;

这样,所有代码都会按预期返回module.exports!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM