实现javascript承诺的最佳实践

时间:2018-06-06 05:55:05

标签: javascript node.js

大家好我是js和异步编程的新手。我使用node.js和express来开始学习js服务器端和异步编程。我有问题要实现像回调承诺异步。我曾经使用过回调,但我认为我的代码变得如此混乱且难以维护。现在我尝试在下面的代码中实现promise。我的问题是:按照我承诺的方式做一个好的做法吗?因为我认为如果我实现"嵌套"那么与回调地狱相比没有什么不同。像我下面的代码一样承诺。使用诺言的最佳做法是什么?谢谢

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

3 个答案:

答案 0 :(得分:4)

Nodejs承诺的最美好的优点之一是避免回调地狱过程。有了承诺,如果你再次将一个嵌套在另一个中,那么你正在创造一个承诺地狱;)。

以下是使用promises的更好方法之一。

链接:

 // 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
}) 

我遇到了下面的链接,它解释了promises的用法。它可能会有所帮助。

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

答案 1 :(得分:2)

目前最佳做法是使用 async / await

  

函数前的 async 一词意味着它总是返回一个promise。如果代码已返回    在其中,然后JavaScript自动将其包装成一个   用这个价值解决了承诺。

     

关键字等待会让JavaScript等到该承诺结算   并返回其结果。

它使代码非常易于处理。

使用起来非常简单,您可以在以下链接中看到。

Link 1

Link 2

Link 3

示例:

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

或者您可以像以下一样使用它:

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

  }

答案 2 :(得分:0)

我说自2018年以来的最佳做法是使用async/await而不是以这种方式使用承诺。

来自MDN的

This article给出了一些如何使用它们的好例子。

举一个非常简单的例子,使用promises代码的一小部分:

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

可以改写为:

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

简要引用上述文章:

  

异步函数可以包含一个等待表达式,该表达式暂停执行异步函数并等待传递的Promise的解析,然后恢复异步函数的执行并返回已解析的值。

此功能已成为Javascript中异步开发在2018年完成的基本部分,我个人认为它是事实上的标准。