node.jstry-catchasynchronous-javascript

Best practice using promises chaining in node JS


I'm little bit confusing in promises. first, I have some ugly code like this:

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;
}

Can anyone explain why presenceNow.check() function is not calling if my ckFilePath does not exist? but if myCkFilePath is exist, my code run so well. And maybe anyone can show me the better code for that case? thanks.


Solution

  • Mixing async/await and promise chains like this is something of a code smell that the author lacked an understand of async/await. It's also something of a mixed metaphor.

    If you refactor it to actually use async/await you get something like this that's a lot easier to understand.

    My suspicion is that your presenceNow.check() method is not being called because the function is taking returning via one of the two return paths above it:

    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;
    }