nodejsasynchronous模块初始化代码

我正在创build一个依赖于另一个asynchronous的模块。 我试图find最好的方式来暴露我的模块,使开发人员使用它发现它很直观。

最初我的模块看起来像这样:

var soap = require('soap'); var service = {}; soap.createClient('http://mysoapservice', function(err, client){ service.myMethod = function(obj, callback){ //dependency on soap module client.soapMethod(obj, function(err, data){ //do something with the response //call other methods etc... var res = "processed "+data['name']; callback(err, res); }); }; }); module.exports = service; 

当然,这里的问题是,在模块代码内部的callback之前调用mymethod会抛出一个exception。

什么是最好的模式使用这种模块?

是否返回特定于其他库的承诺 (q)可接受的scheme? 或者我应该只是返回一个callback,当模块被初始化,并让开发人员处理其余的?

首先,我不会使用单例模式。 如果用户想要多个服务呢? 为此,最好有一个构造函数或工厂。 这提供了更多的devise灵活性,使用户更清楚。 例如:

 // constructor var Service = function() { this.initialized = false; // service is not initialized }; Service.prototype.myMethod = function(...) { // check if initialized if (!this.initialized) return false; // do your stuff here ... }; Service.prototype.initialize = function(..., cb) { // do your initialization and call the callback // also, set this.initialized to true }; // want to have a factory, to provide a "createService" function? // no problem Service.createService = function(..., cb) { var service = new Service(); service.initialize(..., cb); // service will only be usable once initialized, but the user // can still store a reference to the created object to use // in his callback return service; }; module.exports = Service; 

像这样使用它:

 // constructor + initializer var myService = new Service(); service.initialize(..., function(...) { // we have the service, do stuff: myService.myMethod(...); }); // factory method var myService = Service.createService(..., function(...) { // we have the service, do stuff myService.myMethod(...); }); 

在这两种情况下,在init之前调用myMethod()将仅返回false(而不是抛出)。

我喜欢这种模式,因为它与其他stream行模块非常相似,所以用户习惯了它,并且知道期望什么。

我最终做的是这个。 仍然不确定这是否是最佳做法,但符合我的需求。 这样,如果在初始化结束之前调用该方法,函数就会排队。

 /** * An async module * @module asyncModule */ var q = require('q'); var debug = require('debug')('asyncModule'); var service = (function () { //private var obj; var init_defer = q.defer(); //constructor var service = function () { var self = this; //initialize async module setTimeout(function(){ obj = {}; obj._method = function(message, callback){ callback(message+" altered"); }; //resolve defer init_defer.resolve(obj); }, 5000); }; service.prototype.myMethod = function (message, callback) { var self = this; //queue function init_defer.promise.then(function(obj){ debug(self.name); obj._method(message, function(msg){ callback(null, msg); }); }); }; service.prototype.configure = function(options){ this.name = options.name; }; return service; })(); module.exports = new service();