如何使打字稿同步执行?

问题描述 投票:1回答:1

我试图实现一个上传图像功能,我有一个类如下。

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显示为Undefined但另一个是正确的。我检查一步,发现进程(文件)仍将实例myClass而不等待reader.onload完成。我相信这应该是同步问题。任何人都可以帮我改进这段代码吗?谢谢!

typescript async-await synchronization
1个回答
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对象。

© www.soinside.com 2019 - 2024. All rights reserved.