gpt4 book ai didi

javascript - 如何延迟对 javascript 对象的任何方法的所有调用,直到该对象初始化为止?

转载 作者:行者123 更新时间:2023-12-02 16:36:34 25 4
gpt4 key购买 nike

假设这段简单的代码:

/*jslint node: true */
"use strict";

function MyClass(db) {
var self = this;
this._initError = new Error("MyClass not initialized");

db.loadDataAsyncronously(function(err, data) {
if (err) {
self._initError =err;
} else {
self._initError = null;
self.data = data;
}
});
}

MyClass.prototype.getA = function(cb) {
if (this._initError) {
return cb(this._initError);
}
return cb(null, this.data.a);
};

MyClass.prototype.getB = function(cb) {
if (this._initError) {
return cb(this._initError);
}
return cb(null, this.data.b);
};


var db = {
loadDataAsyncronously: function(cb) {
// Emulate the load process from disk.
// Data will be available later
setTimeout(function() {
cb(null, {
a:"Hello",
b:"World"
});
},1000);
}
};

var obj = new MyClass(db);
obj.getA(function (err, a) {
if (err) {
console.log(err);
} else {
console.log("a: " + a);
}
});

obj.getB(function (err, b) {
if (err) {
console.log(err);
} else {
console.log("a: " + b);
}
});

这会产生错误,因为调用 getA 和 getB 方法时 obj 未初始化。我希望在对象初始化之前调用的任何方法都会自动延迟,直到类完成初始化。

解决这个问题的一种方法是这样的:

/*jslint node: true */
"use strict";

function MyClass(db) {
var self = this;
self._pendingAfterInitCalls = [];

db.loadDataAsyncronously(function(err, data) {
if (!err) {
self.data = data;
}
self._finishInitialization(err);
});
}

MyClass.prototype.getA = function(cb) {
this._waitUntiliInitialized(function(err) {
if (err) {
return cb(err);
}
return cb(null, this.data.a);
});
};

MyClass.prototype.getB = function(cb) {
this._waitUntiliInitialized(function(err) {
if (err) {
return cb(err);
}
return cb(null, this.data.b);
});
};

MyClass.prototype._finishInitialization = function(err) {
this._initialized=true;
if (err) {
this._initError = err;
}
this._pendingAfterInitCalls.forEach(function(call) {
call(err);
});
delete this._pendingAfterInitCalls;
};

MyClass.prototype._waitUntiliInitialized = function(cb) {
var bindedCall = cb.bind(this);
if (this._initialized) {
return bindedCall(this._initError);
}
this._pendingAfterInitCalls.push(bindedCall);
};


var db = {
loadDataAsyncronously: function(cb) {
// Emulate the load process from disk.
// Data will be available later
setTimeout(function() {
cb(null, {
a:"Hello",
b:"World"
});
},1000);
}
};

var obj = new MyClass(db);
obj.getA(function (err, a) {
if (err) {
console.log(err);
} else {
console.log("a: " + a);
}
});

obj.getB(function (err, b) {
if (err) {
console.log(err);
} else {
console.log("a: " + b);
}
});

但在我看来,为遵循这种模式的每个类编写的开销似乎很大。

是否有更优雅的方式来处理此功能?

是否存在任何库来简化此功能?

最佳答案

在准备这个问题时,我的脑海中浮现出什么可能是一个好的答案。这个想法是使用工厂函数的概念。上面的代码将被重写为这样。

/*jslint node: true */
"use strict";

function createMyClass(db, cb) {
var obj = new MyClass();
obj._init(db, function(err) {
if (err) return cb(err);
cb(null, obj);
});
}

function MyClass() {
}

MyClass.prototype._init = function(db, cb) {
var self=this;
db.loadDataAsyncronously(function(err, data) {
if (err) return cb(err);
self.data = data;
cb();
});
};

MyClass.prototype.getA = function(cb) {
if (this._initError) return cb(this._initError);
cb(null, this.data.a);
};

MyClass.prototype.getB = function(cb) {
if (this._initError) return cb(this._initError);
cb(null, this.data.b);
};

var db = {
loadDataAsyncronously: function(cb) {
// Emulate the load process from disk.
// Data will be available later
setTimeout(function() {
cb(null, {
a:"Hello",
b:"World"
});
},1000);
}
};

var obj;
createMyClass(db,function(err, aObj) {
if (err) {
console.log(err);
return;
}

obj=aObj;

obj.getA(function (err, a) {
if (err) {
console.log(err);
} else {
console.log("a: " + a);
}
});

obj.getB(function (err, b) {
if (err) {
console.log(err);
} else {
console.log("a: " + b);
}
});
});

我分享这个问答是因为我认为其他人可能会对此感兴趣。如果您认为存在更好的解决方案、处理这种情况的库或任何其他想法,我将不胜感激。

关于javascript - 如何延迟对 javascript 对象的任何方法的所有调用,直到该对象初始化为止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27879501/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com