我正在尝试实现上传图片功能,并且有一个如下的类。
class myClass {
oriData: any;
name: string;
constructor(props) {
this.name = props.name;
this.oriData = this.readFile(props);
}
async readFile(props) {
return await new Promise((resolve, reject) => {
let reader = new FileReader();
reader.readAsDataURL(props);
reader.onload = () => {
let result = reader.result;
resolve(result);
};
reader.onerror = reject;
});
}
}
private async process(file): Promise<myClass> {
try {
let image = await new myClass(file);
console.log(image.oriData);
console.log(image.name);
return Promise.resolve(image);
}
catch(err) {
console.log(err);
}
}
但是,当我尝试获取image.oriData和image.name时,image.oriData显示为“未定义”,但另一个是正确的。我检查了该步骤,发现进程(文件)仍将实例化myClass,而无需等待reader.onload完成。我相信这应该是一个同步问题。谁能帮我改进这段代码?谢谢!
答案 0 :(得分:1)
您可以从JavaScript构造函数返回任何文字,因此这是可能模式:
class DontDoThis {
constructor(props) {
this.name = props.name;
const results = this.readFile(props);
// As a side-effect of the promise completing, set a field
results.then(data => this.oriData = data);
// Force this constructor to be treated as async
// even though we cannot say `async constructor`
return results.then(() => this, () => this);
}
}
async function process(...) {
const complexData = await new DontDoThis(...);
}
也就是说,仅仅拥有一个构造最终值的函数要好得多:
interface ImageData { name: string, oriData: any };
// This can also be a static method, e. g. `ImageData.create(...)`
async function ComplexData(props): Promise<ImageData> {
return readFile(props).then(data => ({name: props.name, oriData: data}));
}
async function process(props) {
const complexData = await ComplexData(props);
}
ImageData
可以是类而不是接口-要注意的关键是它不能部分构造-ComplexData
成功并产生ImageData
对象,或者失败而且你一无所有。您永远不会有不安全的使用,因为它是半初始化的ImageData
对象。