【问题标题】:Converting Promises Code to async await and mocking test cases?将 Promises 代码转换为异步等待和模拟测试用例?
【发布时间】:2020-01-30 00:27:49
【问题描述】:

如何将下面嵌套了promise和await的函数转换为只使用await或只使用promises?

const test = (url, id) => {
  return new Promise((_resolve, _reject) => {
    if (isValidUrl(url)) {
      let storage = new Storage(Indexdb, id);
      const cae = new valueExtract(url);
      cae.fetch()
        .then(data => {
          new zip(data)
            .then(obj => obj.getZip())
            .then(obj => obj.getList())
            .then(list => {
              return new Promise(async (resolve, reject) => {
                try {
                  let sI = storage.connection;
                  await Promise.all(Object.keys(list).map(async (fileName, index) => {
                    let blob = await new FileExtractor(list[fileName]);
                    await sI.setItemForce(
                      fileName,
                      new StoreObject(
                        fileName,
                        'testData',
                        blob
                      ).dataObject
                    )
                  }))
                  _resolve(sI);
                } catch (err) {
                  _reject(err)
                }
              })
            })
            .catch(err => _reject(err))
        })
        .catch(err => _reject(err))
    } else {
      _reject('Invalid URL')
    }
  })
};

我无法做到这一点,但它永远无法解决

const test = async (url, id) => {
  if (isValidUrl(url)) {
    try {
      let storage = new Storage(Indexdb, id);
      const cae = new valueExtract(url);
      const data = await cae.fetch();
      return new ZIPExtractor(data)
        .then(obj => obj.getZip())
        .then(obj => obj.getList())
        .then(list => {
          return async (resolve, reject) => {
            try {
              let sI = storage.connection;
              await Promise.all(Object.keys(list).map(async (fileName, index) => {
                let blob = await new FileExtractor(list[fileName]);
                await sI.setItemForce(
                  fileName,
                  new StoreObject(
                    fileName,
                    'testData',
                    blob
                  ).dataObject
                )
              }))
            } catch (err) {
              throw new Error(err)
            }
          }
        })
        .catch(err => _reject(err))
    } catch (e) {
      throw new Error('Invalid URL')
    }
  }
};

还有我们如何为这类函数编写测试用例,这样我们就不需要传入实际的网络 url 并开玩笑地模拟了。

【问题讨论】:

  • 即使不使用 async/await,您的 promise 代码也可能会更简单很多。这里的嵌套是完全不需要的,你应该避免new Promise()

标签: javascript promise async-await


【解决方案1】:

应该实现,但是使用 async (resolve, reject) { … }return。你一开始就不应该使用它,你可以省略它:

const test = async (url, id) => {
  if (!isValidUrl(url)) {
    throw new Error('Invalid URL')
  }
  const storage = new Storage(Indexdb, id);
  const cae = new valueExtract(url);
  const data = await cae.fetch();
  const obj = await new ZIPExtractor(data); // shudder. A constructor should never return a promise
  const zip = await obj.getZip();
  const list = await zip.getList();
  const sI = storage.connection;
  await Promise.all(Object.keys(list).map(async (fileName, index) => {
    const blob = await new FileExtractor(list[fileName]);
    const store = new StoreObject(fileName, 'testData', blob);
    await sI.setItemForce(fileName, store.dataObject);
  }));
  return sI; // or something?
}

【讨论】:

  • 感谢您的快速回复,// might need some awaits 是什么意思以及我们如何测试这种方法.. 如果您添加这两个并解释一些逻辑,真的很有帮助不太擅长异步等待。
  • 即使在使用 await 将 const list = obj.getZip().getList(); 拆分为多行之后也是如此。 ` const fileList = await obj.getZip();常量列表 = 等待文件列表.getFileList(); ` 它不起作用,我想我们忘了返回是这样的
  • 如果您能对单元测试有所了解,也感谢@Bergi。非常感谢。寻求帮助
  • 是的,我就是这个意思。我也忘记了你想返回一些东西,这在原始代码中并不清楚。
  • 我认为如何测试这是一个 entirely separate question,但您可能想要模拟所有构造函数,例如 StorageZipExtractorFileExtractor
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
  • 2016-04-26
  • 2020-02-28
相关资源
最近更新 更多