【问题标题】:Chek the return from a promise function before proceeding. Wrong approach?在继续之前检查 promise 函数的返回值。方法错误?
【发布时间】:2015-02-24 09:19:36
【问题描述】:

背景:我有 PHP 背景,这是我第一个使用 MEAN 堆栈的应用程序。

我需要保存一条记录,但在此之前我必须检查数据库中是否已经保存了相同 ID 下的任何记录。 在 PHP 中,我会做这样的事情: 一旦用户点击“保存”: 1) 调用函数检查是否已经存在具有该id的条目 2) 如果没有,调用保存函数。

在 Javascript 中,我对 Promises 等感到有些困惑。

有人可以给我点灯吗?

现在,我正在执行以下操作: 在保存 api 中,我调用此函数来检查数据库中是否已存在记录: recordExists = findTranscationByBill(billId);

function findTransactionByBill(billId){
     results = new promise(function(resolve, reject){
        Transactions.find({billId : billId},function(err, transactions){
            if(err)
                reject("Error: "+err);

            //console.log(transactions);
            resolve(transactions);
         });  
     });

     results.then(function(data){
        console.log('Promise fullfilled: '+ data);
     }, function(error){
        console.log('Promise rejected: ' + error);
     }); 

  return $results;
}

问题是我认为我没有正确使用 Promise,因为我的变量没有被填充(因为它是异步的)。 在 console.log 中,我看到承诺正在兑现,但是变量返回为 [object Object] 我被这个问题困住了,因为我不知道我是否应该继续以 PHP 的思维方式思考,或者是否在 Javascript 中使用了不同的方法。

提前致谢!

【问题讨论】:

    标签: javascript node.js mongoose promise


    【解决方案1】:

    我认为正确的功能是:

    function findTransactionByBill(billId){
      var results = new promise(function(resolve, reject){
         Transactions.find({billId : billId},function(err, transactions){
            if(err) {
               reject(err);
            } else { 
               if (transactions.length === 0) {
                  reject('No any transaction');
               } else {
                 //console.log(transactions);
                 resolve(transactions);
               }
         });  
     });
    
     results.then(function(data){
        console.log('Promise fullfilled: '+ data);
     }, function(error){
        console.log('Promise rejected: ' + error);
     }); 
    
     return results;
    }
    

    然后像这样使用它:

    recordExists = findTranscationByBill(billId);
    recordExists.then(function() {
        // resolved, there are some transactions
    }, function() {
        // rejected. Error or no any transactions found
        // may be you need to check reject result to act differently then no transactions and then error
    });
    

    【讨论】:

      【解决方案2】:

      在我看来,你也可以为此使用回调,既然 MongoDB 有一个 count 方法,为什么不使用它

      function findTransactionByBill(billId, callback){
      
          Transactions.count({billId : billId}, function(err, count){
              if (err) {
                  callback(err, false);
              } else {
                  callback(null, count !== 0);
              }
          });
      
      }
      

      并使用它

      findTransactionByBill(billId, function(err, exists) {
         if (err) {
            // handle errors
         } else if ( ! exists ) {
            // insert into DB
         }
      }
      

      【讨论】:

      • 不客气。请记住,promise 非常很棒,它们可以让你摆脱回调地狱,但同时,普通的旧回调是 Node 中大多数事情的方式,它们对于简单的便捷方法也能正常工作,比如这个。
      • 我不同意,如果你像 OP 那样使用承诺,承诺永远不会很好,因为你仍然在做回调(有所有的缺点)但增加了仪式。延迟反模式是真实存在的。
      【解决方案3】:

      我假设您使用的是 mongodb 本机驱动器。

      我认为 mongodb 不支持内置的承诺。所以你必须通过 promise 库的一点帮助来promisify它。如果您想使用蓝鸟,请参考this

      promisifying 之后,代码应该是这样的(使用 bluebird):

      Promise = require('bluebird');
      // Promisify...
      var _db = null;
      var client = MongoClient.connectAsync('mongodb://localhost:27017/test')
          .then(function(db) {
              _db = db
              return db.collection("myCollection").findOneAsync({ id: 'billId' })
          })
          .then(function(item) {
            if (item)
              _db.save(item);
          })
          .catch (err) {
            // error handling 
          }
      

      上面的代码并不完美,因为它引入了一个全局变量,所以更好的版本可能是

      Promise = require('bluebird');
      // Promisify...
      var client = MongoClient.connectAsync('mongodb://localhost:27017/test')
          .then(function(db) {
              return Promise.prop({ 
                item: db.collection("myCollection").findOneAsync({ id: 'billId' }, 
                db: db
              })
          })
          .then(function(result) {
            var item = result.item;
            var db = result.db
            if (item)
              db.save(item);
          })
          .catch (err) {
            // error handling 
          }
      

      您需要查看bluebird 以了解如何使用它。它们还有许多其他的 promise 库,例如 q、when,但都是类似的东西。

      【讨论】:

        猜你喜欢
        • 2020-03-01
        • 1970-01-01
        • 2011-08-16
        • 2020-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-26
        • 2022-10-08
        相关资源
        最近更新 更多