javascript - 如何创建包含异步调用的 Javascript (es5) 构造函数
问题描述
我正在尝试创建一个构造函数,其中包括对 indexedDB 或 localStorage 的调用以检索一些数据(如果存在),然后从缓存或给定(默认)数据中填充它的值。
我让它工作,但不知何故破坏了我的代码。鉴于我的编程方法是“用棍子敲打直到它起作用”,代码绝对是一团糟。所以我将问题简化为一个人为的例子,它以同样的方式失败。
删除异步函数 (setTimeout) 可以解决问题,但是我的代码将无法正常工作。
var person = (function(){
function privateFn (value){
return value;
}
function private_asyncFn(value, callback){
setTimeout(function () {
return callback(value);
}, 10);
}
var DATA, NUM;
var personConstructor = function(name, age, gender, callback){
this.name = privateFn(name);
this.gender = privateFn(gender);
DATA = DATA || [];
NUM = NUM || 0;
this.num = NUM;
private_asyncFn(age, function(ret){
DATA[NUM++] = { name: this.name, age: ret };
if (callback instanceof Function) return callback(this.name);
}.bind(this));
};
personConstructor.prototype.getAge = function () {
if (this.gender === "male") return DATA[this.num].age;
else return DATA[this.num].age < 20 ? 18 : (Math.floor(DATA[this.num].age / 10) - 1) + "9 and holding";
};
return personConstructor;
})();
var name1;
var person1 = new person("jill", 32, "female", function(name){
name1 = name;
});
var age1 = person1.getAge(); //Uncaught TypeError: Cannot read property 'age' of undefined????
我在 SO 上看到使用类和承诺以及异步/等待的其他代码,但我不明白这一切是如何工作的,所以这段代码有点“老派”,对此感到抱歉。
在此示例中,您能否在新人员初始化之后立即检索人员的年龄?
解决方案
没有办法制作异步构造函数。相反,您想要做的可能是创建一个异步函数,该函数将在异步操作完成后生成您构造的对象。我会给你一个更具体的例子,但坦率地说,我不明白你的代码的异步部分试图做什么。不过,这是一个如何完成此操作的示例:
function Person(name, age, gender) {
this.name = name
this.gender = gender
this.age = age
}
Person.prototype.getAge = function() {
return this.age
}
Person.create = function create(name, age, gender, done) {
var person = new Person(name, age, gender)
setTimeout(function () {
done(null, person)
}, 1000)
}
Person.create("jill", 32, "female", function (person) {
person.getAge()
})
如果您不需要支持非常旧的浏览器,我建议您使用 Promises 和 ES6 类。
class Person {
static create(name, age, gender) {
return new Promise(resolve => {
const person = new Person(name, age, gender)
resolve(person)
})
}
constructor(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
getAge() {
return this.age
}
}
Person.create("jill", 32, "female")
.then((person) => {
person.getAge()
})
当您发布下一个 SO 问题以给出您的代码试图实现的目标的真实示例时,这将很有帮助 -getAge
根据性别返回不同的结果没有多大意义:)
推荐阅读
- android - 是否可以将 biometric_storage 存储到可以存储多个用户指纹的集中式数据库中?
- c# - Monitor 是否使用内核维护的布尔变量?
- node.js - 如何在不寻常的地方从 node_modules 获取 VSCode 中的智能感知?
- javascript - 如何使用脚本标签将 php 值发送到 javascript?
- php - 安装 PHP 国际扩展
- c# - Record 'Lenses' - with 表达式的表达式树
- python - Python 简介:基于文本的冒险
- python - 如何使用 winsound 模块同时播放多个声音?
- go - 带有 Dockerfile/go.mod 文件的私有仓库的 Go 构建失败
- laravel - 如何在控制器中使用失败方法验证