首页 > 解决方案 > 如何避免显式构造反模式并仍然保持缩进/回调低

问题描述

假设我们有一个函数,它调用相当数量的异步函数,如下所示:

downloadAndAssemble = () => 
  new Promise(async (resolve, reject) => {

    if (!(await checkAvailableDiskSpace())) {
      resolve(false);
      return;
    }

    try {
      // Download all
      let files  = await this.downloadAll();

      // Assemble File from downloaded snippets.
      const assembledFile = await buildFile(files).catch(error => reject(error));

      // Save assembled file.
      resolve(true);
    } catch (err) {
      reject(err);
    } finally {
      const dirExists = await fs.exists(tmpFolderPath);
      if (dirExists) await fs.unlink(tmpFolderPath);
    }
  });

我看到的第一个问题是根据这篇 SO 文章new Promise(async (resolve, reject) => {这是一种反模式。

我从那篇文章中得到的一般想法是重用 Promises(如果可用),而不是创建新的 Promises。

如果我遵循这个 SO 答案中的建议,我应该在函数.then.catch逻辑流程中使用现有的 Promises。

但这会导致更多的缩进(即每个使用的承诺一个),我认为承诺应该有助于消除。

.catch(error => reject(error))代码中可以看出,它与处理其中包含的 Promises 引发的错误不是很一致。

标签: javascriptpromisees6-promise

解决方案


  downloadAndAssemble = async () =>  {
    if (!(await checkAvailableDiskSpace())) {
      return false;
    }

     try {
       // Download all
       let files  = await this.downloadAll();

       // Assemble File from downloaded snippets.
       const assembledFile = await buildFile(files);

      // Save assembled file.
      return true;
    } finally {
       const dirExists = await fs.exists(tmpFolderPath);
       if (dirExists) await fs.unlink(tmpFolderPath);
    }
};

如果你调用一个async函数,它会隐式地为你创建一个承诺,如果你解决,如果你return拒绝throw,所以没有必要“手动”创建和管理承诺。

.catch(error => reject(error))没有什么意义,因为await承诺会自动让错误冒泡。在您的代码中,这绕过了try { ... } catch { ... }可能不需要的。

这同样适用于} catch (err) { reject(err); },await是你所需要的。


推荐阅读