简体   繁体   English

实现JavaScript Promise的最佳做法

[英]Best practice of implementing javascript promise

Hi guys I am pretty new to js and asynchronous programming. 大家好,我对js和异步编程非常陌生。 I use node.js and express to start learning js serverside and asynchronous programming. 我使用node.js并表示要开始学习js服务器端和异步编程。 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. 现在,我尝试在下面的代码中实现promise。 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. 因为我认为,如果我像下面的代码那样实现“嵌套” promise,则与回调地狱相比没有什么不同。 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');
        }
    }

One of the most beautiful advantages of Nodejs promises is to avoid the callback hell process. Nodejs承诺的最美丽的优势之一就是避免了回调地狱过程。 And with promises, if you are again nesting one inside the other then you are creating a promise hell ;) . 有了promise,如果您再次将一个嵌套在另一个内,那么您将创建一个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/ https://www.joezimjs.com/javascript/javascript-asynchronous-architectures-events-vs-promises/

For now best practice is to use async/await . 目前,最佳实践是使用async / await

The word async before a function means it always returns a promise. 函数前的单词async表示它总是返回promise。 If the code has return in it, then JavaScript automatically wraps it into a resolved promise with that value. 如果代码已返回,则JavaScript会自动将其包装为具有该值的已解析的Promise。

The keyword await makes JavaScript wait until that promise settles and returns its result. 关键字await使JavaScript等待该承诺完成并返回其结果。

It makes code pretty and easy to handle. 它使代码漂亮且易于处理。

It is quite simple to use, as you can see on following links. 正如您在以下链接中看到的那样,它非常易于使用。

Link 1 . 链接1

Link 2 . 链接2

Link 3 连结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);

  }

I'd say best practice as of 2018 is to use async/await instead of using promises in this way. 我会说截至2018年的最佳实践是使用async/await而不是以这种方式使用promises。

This article from MDN gives some good examples of how they can be used. MDN的这篇文章提供了一些很好的示例,说明了如何使用它们。

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. 异步函数可以包含await表达式,该表达式暂停异步函数的执行并等待传递的Promise的分辨率,然后恢复异步函数的执行并返回解析的值。

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. 此功能已成为Java异步开发在2018年完成的基本部分,我个人认为这是事实上的标准。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM