我想用NodeJS执行以下操作。创建以下对象数组,其中每个对象在初始化时都有不同的局部变量。
obj.js
var Obj = function (_id) {
this.id = _id;
var that=this;
db.getData(_id,function(collection){ //this method is asynchronous
collection.toArray(function(err, items) {
that.data=items;
});
});
}
Obj.prototype.data = [];
module.exports = Obj;
app.js
var arr=[];
arr.push(new obj(24));
arr.push(new obj(41));
arr.push(new obj(24));
arr.push(new obj(42));
//then do tasks with the arr
但是由于arr构造函数是同步的,因此当我使用arr进行计算时,它们可能无法获取所有数据。那么如何处理这种情况呢?我想确保在使用它们之前成功创建了所有对象。
提前致谢。
答案 0 :(得分:2)
data
将在内存中共享,您应该在构造函数中使用this.data=[]
。
其次,正如@mscdex所说,将你的方法转移到原型中,比如说
Obj.prototype.load=function(){
//code here...
}
然后你的代码如下:
var Obj = function(_id){
this.id=_id;
this.data = [];
}
Obj.prototype.load = function(){
var that = this;
db.getData(this.id,function(collection){ //this method is asynchronous
collection.toArray(function(err, items) {
that.data=items;
});
});
return that;
}
最后,你的问题,你怎么知道所有这些都准备好了。
Obj.prototype.ready = [];
Obj.prototype.loaded=function(){
this.ready.push(1);
if(this.ready.length == Obj.target)
Obj.onComplete();
}
Obj.notifyme = function(callback,len){
Obj.target = len;
Obj.onComplete = callback;
}
上面的代码设置了一个数组来计算加载完成实例(使用数组,因为无法从实例' s __proto__
引用中读取基本值)。所以你应该做的是将这个事件(函数)添加到load
,所以代码最后可能如下:
Obj.prototype.load = function(){
var that = this;
db.getData(this.id,function(collection){ //this method is asynchronous
collection.toArray(function(err, items) {
that.data=items;
that.loaded();
});
});
return that;
}
var args = [24,41,42];
Obj.notifyme(function(){/*then do tasks with the arr*/},args.length);
var arr = args.map(function(arg){
return new Obj(arg).load();
});
告诉函数notifyme
回调工作和实例数。最后一个问题是,如果您执行此例程多次,则应重置target
和callback
,因为它们是Obj
全局事物。
答案 1 :(得分:1)
我会使用Promise模式。这是这种方法的原型。我使用本机浏览器Promise进行实现和测试。对于NodeJS,您可以将Kowal的Q实现与类似(或非常接近)的API一起使用。
var Obj = function (_id) {
this.id = _id;
var that = this;
this.promise = function() {
return new Promise(function(resolve) {
db.getData(_id, function (collection) {
collection.toArray(function (err, items) {
that.data.push(items);
resolve(that);
});
});
});
}();
};
Obj.prototype.data = [];
function objFactory(args) {
var promises = args.map(function(el) {
return new Obj(el).promise;
});
return Promise.all(promises);
}
objFactory([24, 25, 41, 42]).then(function(arr) {
console.log(arr, arr[0].data);
});
这个想法是,当objFactory
返回的promise对象解析时,它将调用相应的then
回调,在其中使用data
是可靠的,因为它已经被填充了时间。
这是我正在测试代码的浏览器demo。您必须为NodeJS环境采用它。但这个想法仍然是一样的。
例如,使用Kris Kowal的Q,它将是这样的:
this.promise = function() {
var deferred = Q.defer();
db.getData(_id, function (collection) {
collection.toArray(function (err, items) {
that.data.push(items);
deferred.resolve(that);
});
});
return deferred.promise;
}();
和Q.all
代替Promise.all
。