在数据范围内通过回调函数传递数据

时间:2017-02-07 08:40:53

标签: javascript node.js

背景

我的问题是了解范围以及如何正确使用回调函数。在我尝试计划时,我似乎无法将事件串起来。我在阅读帖子时遇到了麻烦,并将它们与当前的问题联系起来。我想我真正没有得到的是如何实现逻辑。

问题

我有几个场景导致我的应用程序出现问题。它们都围绕着我需要的数据不在范围内的情况。但该函数已经具有回调函数。

示例

此函数将数据插入数据库。

   updateProfile: function (req, res) {
    pool.getConnection(function (err, connection) {
        var email = req.body.email;
        var sql = 'INSERT INTO rw_users SET email = ?';
        var params = [email];

        connection.query(sql, params, function (err, results, fields) {
            if (err) {
                res.status(500).send();
                throw err;
            }
            connection.release();
        });
    });
},

下一个功能需要刚刚创建的用户的ID。

 createCustomerProfile: function (email, id) {
            merchant.createCustomerProfile(email, id, function callback(merchantRes){
                    pool.getConnection(function (err, connection) {
                var sql = 'UPDATE rw_user SET auth_customer_id = ? WHERE email = ?';
                var params = [merchantRes, email];
                connection.query(sql, params, function (err, results, fields) {
                    if (err) {
                        throw err;
                    }
                    console.log('new customer created at authorize.net');
                });
            });
          });
        }, 

在函数updateProfile()中,我在数据库中创建了一个新用户。在第二个函数createCustomerProfile()中,我需要在函数1中输入的新创建用户的ID。

请告诉我一种处理这类功能的方法。我需要第一个进程的数据,所以我可以在第二个函数中使用它。这会变得最糟糕,因为当函数2完成时,它将在其响应中产生一个新的customerID。该响应还需要进行另一个数据库查询以使用其ID更新该行。然后,一旦完成这两个函数,我需要再次查询数据库以返回整行。

要打破这种局面,

  1. 在数据库中创建用户。
  2. 使用在功能1中创建的新用户的ID和电子邮件。在功能2中创建具有authorize.net api的新客户帐户ID。
  3. 将authorize.net API的响应中的新客户ID插入到在第一个函数中创建的新用户行。
  4. 返回整行。
  5. 我的问题要清楚。什么是可能的解决方案,用于能够执行我的列表中的任务并清楚地实现它们以便按顺序处理,以便当它存在于范围内时我可以使用每个响应?

1 个答案:

答案 0 :(得分:1)

实现程序的最简单方法是使用嵌套回调,但这很容易变得混乱,很难维护代码。 我们可以使用promises或generator来以更优雅的方式执行此操作。 首先,让我们看看下面的代码(简单的代码)。

     const test1= () => {
         return new Promise((resolve,reject)=>{
              setTimeout(function(){ <-- async operation
                 resolve(10);
             })
         })
     }

     const test2= (data) => {
         return new Promise((resolve,reject)=>{
                    setTimeout(function(){ <-- async operation
                         resolve(data+20)
                    })
                })
     }

     test1()
     .then(test2)
     .then((finalData)=>{console.log(finalData)});

这将给我们30的价值。那么这是如何工作的。 test1和test2都返回promise对象,该对象具有方法名称&#39;然后&#39;。

   new Proimse((resolve,reject)=>{ async operation comes here , when the operation 
done successfully , we resolve it, otherwise reject , })

then方法需要一个函数,我们可以通过resolve函数传递参数。但是只需要一个参数,因此如果需要多个参数,则需要对象或数组。如果你能理解上面的代码,那么让我们重构你的代码

     getConnection:function(req,res){
           return new Promise((resolve,reject)=>{
                 pool.getConnection(function (err, connection) {
                        if(err) return reject(err);
                        resolve({connection,req,res});
             });
             })
     },

     updateProfile:function(obj){
         const { connection,req,res } = obj;
         return new Promise((resolve,reject)=>{
             var email = req.body.email;
             var sql = 'INSERT INTO rw_users SET email = ?';
             var params = [email];
             connection.query(sql, params, function (err, results, fields) {
                     if (err) return reject(err);
                     resolve({email,results,connection});
             });
         })
     },

     createCustomerProfile: function (obj) {
                   const { email,results,connection } = obj;
                     return new Promise((resolve,reject)=>{
                         merchant.createCustomerProfile(email, results.id, function callback(merchantRes){
                                 var sql = 'UPDATE rw_user SET auth_customer_id = ? WHERE email = ?';
                                 var params = [merchantRes, email];
                                 connection.query(sql, params, function (err, results, fields) {
                                         if (err) {
                                                 throw err;
                                         }
                                         console.log('new customer created at authorize.net');
                                         connection.release();
                                 });
                     });
                     })
  }

    yourModule.getConnection(req,res)
              .then(yourModule.updateProfile)
              .then(yourModule.createCustomerProfile)
              .catch((err)=>{console.log(err)})

现在您需要修改此代码,以便适用于您的模块。

相关问题