0

Hi guys I am pretty new to js and asynchronous programming. I use node.js and express to start learning js serverside and asynchronous programming. I have probleom to implement something like callback promise async. I had used callback but I think my code becomes so messy and hard to maintain. Now I try to implement promise in my code below. My question is: do the way I use promise there is a good practice? Cause I think There's no different comparing to callback hell if I implement "nested" promise like my code below. How is the best practice of using promise? Thank you

update_data_profil(req, res) {
        var nama_unit_org = req.body.nama_unit_org;
        var nama_ketua_unit_org = req.body.nama_ketua_unit_org;
        var nip_nim = req.body.nip_nim;
        var email = req.body.email;
        var no_hp = req.body.no_hp;
        var params;
        var user;
        if (helper.isExist(nama_unit_org) && helper.isExist(nama_ketua_unit_org) && helper.isExist(email)
            && helper.isExist(nip_nim) && helper.isExist(no_hp)) {
            if (nip_nim !== req.user.nip_nim) {
                params = {
                    nip_nim: nip_nim
                }
                user = new User_Model(params);
                user.getDataProfilByNIPorNIM()
                    .then(function (result) {
                        if (result) {
                            req.flash('message_err', "NIP/NIM telah dipakai akun lain.");
                            res.redirect('/manajemen_profil');
                        }
                        else {
                            params = {
                                id_user: req.user.id_user,
                                nip_nim: nip_nim,
                                nama_ketua_unit_org: nama_ketua_unit_org,
                                nama_unit_org: nama_unit_org,
                                email: email,
                                no_hp: no_hp,
                            };
                            user = new User_Model(params);
                            user.editDataProfil()
                                .then(function () {
                                    params = {
                                        session_id: req.sessionID
                                    };
                                    user = new User_Model(params);
                                    user.clearSession()
                                        .then(function () {
                                            req.flash('message_success', 'Edit data profil berhasil. Silahkan login untuk melanjutkan');
                                            res.render('index/login',
                                                {
                                                    message_success: req.flash('message_success')
                                                });
                                        }).catch(function (err) {
                                            req.flash('message_err', "Internal server error");
                                            res.redirect('/');
                                        });
                                })
                                .catch(function (err) {
                                    req.flash('message_err', "Internal server error.");
                                    res.redirect('/');
                                });
                        }

                    }).catch(function (err) {
                        req.flash('message_err', "Internal server error.");
                        res.redirect('/');
                    })
            }
            else {
                params = {
                    id_user: req.user.id_user,
                    nama_ketua_unit_org: nama_ketua_unit_org,
                    nama_unit_org: nama_unit_org,
                    email: email,
                    no_hp: no_hp
                };
                user = new User_Model(params);
                user.editDataProfil()
                    .then(function () {
                        req.flash('message_success', "Berhasil update profil.");
                        res.redirect('/manajemen_profil');
                    })
                    .catch(function (err) {
                        req.flash('message_err', "Internal server error");
                        res.redirect('/manajemen_profil');
                    });
            }
        }
        else {
            req.flash('message_err', "Tidak boleh ada field yang kosong!");
            res.redirect('/manajemen_profil');
        }
    }
4
  • 2
    No, that is not good practice. You should be chaining the promises (and possibly separating them into their own functions for better readability) rather than nesting them. Commented Jun 6, 2018 at 5:56
  • Can u give me example with my code above? Commented Jun 6, 2018 at 5:57
  • You should also do your best to use const and never var, especially with anything asynchronous Commented Jun 6, 2018 at 5:59
  • Return a promise for each then so you can chain another then to it. Commented Jun 6, 2018 at 6:00

3 Answers 3

4

One of the most beautiful advantages of Nodejs promises is to avoid the callback hell process. And with promises, if you are again nesting one inside the other then you are creating a promise hell ;) .

Below is one of the better approach to use promises.

Chaining:

 // Promises example using 'then'
user.getDataProfilByNIPorNIM().then(function(user) {
    ...
    return user.editDataProfil();
}).then(function(editDataProfilResults) {
    ....
    return user.clearSession();
}).then(function(clearSessionResult) {
   ....
   return
}).catch(function(err){
   .....
   process error
}) 

I have come across below link, which explain usage of promises. It might be helpful.

https://www.joezimjs.com/javascript/javascript-asynchronous-architectures-events-vs-promises/

Sign up to request clarification or add additional context in comments.

1 Comment

I confuse how to place ifelse if I implement chained promise like that.
2

For now best practice is to use async/await.

The word async before a function means it always returns a promise. If the code has return in it, then JavaScript automatically wraps it into a resolved promise with that value.

The keyword await makes JavaScript wait until that promise settles and returns its result.

It makes code pretty and easy to handle.

It is quite simple to use, as you can see on following links.

Link 1.

Link 2.

Link 3

Example:

 async function getData(url) {
  let v;
  try {
    v = await downloadData(url); 
  } catch(e) {
    v = await downloadFail(url);
  }
  return processAnother(v);
}

or you can use it like :

async FunctionFun( ) {

  const groups = await this.variableGroupsService.find();

  const groups2 = await this.pageMarkersService.find();

  const groups3  = await this.funnelStepsService.findFunnelSteps()

  return anyOtherFunction(groups, groups2, groups3);

  }

Comments

0

I'd say best practice as of 2018 is to use async/await instead of using promises in this way.

This article from MDN gives some good examples of how they can be used.

To give a very simple example, a small part of your code using promises:

user.getDataProfilByNIPorNIM()
    .then(function (result) {
        if (result) {
            req.flash('message_err', "NIP/NIM telah dipakai akun lain.");
            ...
    });

could be rewritten as:

try {
    const result = await user.getDataProfilByNIPorNIM();
} catch(e) {
    // catch errors here.
}

To briefly quote the abovementioned article:

An async function can contain an await expression that pauses the execution of the async function and waits for the passed Promise's resolution, and then resumes the async function's execution and returns the resolved value.

This feature has become a fundamental part of how asynchronous development in Javascript is done in 2018, and I'd personally say it's a de-facto standard.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.