在节点 JS 中使用承诺链接的最佳实践

Best practice using promises chaining in node JS

我对承诺有点困惑。首先,我有一些像这样的丑陋代码:

async function presence(ctx) {
    try {
        var prsenceData = [];
        var isSuccess = Boolean(false);
        var ckFilePath = "./somepath/cookie.json";

        if (!fs.existsSync(ckFilePath)) {
            await menuLogin.login(ctx).then(login => {
                isSuccess = Boolean(login[0].status);
                myCk.saveCookies(login[0].cookies, ckFilePath);
                if (!isSuccess) {
                    myCk.deleteCookies(ckFilePath);
                    return false;
                }
            });
        } else {
            await myCk.checkToDelete(ckFilePath).then(isDel => {
                if (isDel) {
                    return false;
                }
            });
        }
        await presenceNow.check(fs.existsSync(ckFilePath), ctx).then(data => {
            for (let id = 0; id < data[0].pesan.length; id++) {
                console.log(data[0].pesan[id]);
            }
            for (let id = 0; id < data[0].id.length; id++) {
                presenceData.push(data[0].id);
            }
            if (data[0].pesan.length == 0 && fs.existsSync(ckFilePath)) {
                myCk.deleteCookies(ckFilePath);
            }
        });
    } catch (e) {
        console.log(e);
    }

    return presenceData;
}

如果我的 ckFilePath 不存在,谁能解释为什么 presenceNow.check() 函数没有被调用?但如果 myCkFilePath 存在,我的代码 运行 就很好。也许任何人都可以向我展示该案例的更好代码?谢谢。

像这样混合 async/await 和承诺链是一种代码味道,作者缺乏对 async/await 的理解。这也是一个混合的隐喻。

如果你重构它以实际使用 async/await 你会得到这样的东西,它更容易理解。

我怀疑你的 presenceNow.check() 方法没有被调用,因为函数正在通过它上面的两个 return 路径之一进行 returning:

  • 文件存在并且myCk.checkToDelete() returns true,或
  • 文件不存在,登录不成功
const fs = require('fs/promises');

async function presence(ctx) {
  var presenceData = [];
  var isSuccess = false;
  var ckFilePath = "./somepath/cookie.json";
  let ckFilePathExists = await fs.access(ckFilePath);

  if (ckFilePathExists) {
    const isDel = await myCk.checkToDelete(ckFilePath);
    if (isDel) {
      return false;
    }
  } else {
    const login = await menuLogin.login(ctx);
    const isSuccess = login[0].status

    myCk.saveCookies(login[0].cookies, ckFilePath);

    if (!isSuccess) {
      myCk.deleteCookies(ckFilePath);
      return false;
    }

  }

  ckFilePathExists = await fs.access(ckFilePath)
  const data = await presenceNow.check(ckFilePathExists, ctx);

  for (let id = 0; id < data[0].pesan.length; id++) {
    console.log(data[0].pesan[id]);
  }

  for (let id = 0; id < data[0].id.length; id++) {
    presenceData.push(data[0].id);
  }


  if (data[0].pesan.length == 0 && await fs.access(ckFilePath) ) {
    myCk.deleteCookies(ckFilePath);
  }


  return presenceData;
}