将Promises Code转换为await和模拟测试用例?

时间:2020-01-29 13:52:53

标签: javascript promise async-await

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

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和嘲笑。

1 个答案:

答案 0 :(得分:2)

应该 完成,但是您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?
}