2017-05-29 22 views
-3

これは情報がたくさんあるトピックですが、まだ解決できません。ループ内でAsyncが約束します

私は、mysqlサーバに接続するNodeJで作業しています。配列を持っています。配列を繰り返し処理する必要があります。データはmysqlサーバに問い合わせる必要がありますクエリの結果が得られるまでforループの待機が必要ですが、私は多くのことを試しましたが、今はbluebirdの各メソッドで試していますが、まだ正しく動作していません。これが私のコードです。

初期関数は、事前に

おかげNotification.getByUserある

'use strict'; 
 
var Promise = require("bluebird"); 
 

 
module.exports = function(Notifications) { 
 
    Notifications.execute = function(sql, itemId) { 
 
    return new Promise((resolve, reject) => { 
 
     this.dataSource.connector.execute(sql, (e, result) => { 
 
     console.log('-----RESULT----', itemId); 
 
     console.log(result); 
 
     console.log('-----ERROR-----', itemId); 
 
     console.log(e); 
 
     if (result.length === 0) { 
 
      resolve(false); 
 
     } else { 
 
      resolve(true); 
 
     } 
 
     }); 
 
    }); 
 
    }; 
 
    Notifications.isMatching = function(item, user, type) { 
 
    return new Promise((resolve, reject) => { 
 
     console.log(type, item, user); 
 
     if (item !== null) { 
 
     if (item !== user) { 
 
      resolve(false); 
 
     } 
 
     } 
 

 
     resolve(true); 
 
    }); 
 
    }; 
 
    Notifications.getByUser = function(userId, isZolver, countryId, cityId, userState, cb) { 
 
    var where = { status: 1 }; 
 
    var plainText = ''; 
 
    var items = Notifications.find({ where }); 
 
    Promise.each(items, item => { 
 
     return Notifications.isMatching(item.isZolver, isZolver, 'isZolver') 
 
     .then(() => { 
 
      Notifications.isMatching(item.cityId, cityId, 'cityId'); 
 
     }) 
 
      .then(() => { 
 
      if(item.extraCondition !== null && item.extraCondition !== '') { 
 
       var sql = item.extraCondition.replace(/:user_id/g, userId); 
 
       // console.log(sql); 
 
       Notifications.execute(sql, item.id) 
 
       .then(render => console.log('extraCondition', render)); 
 
      } else { 
 
       console.log('extraCondition', true); 
 
      } 
 
      }); 
 
    }).then(res => { 
 
     // console.log('res del loop', res); 
 
    }); 
 
    cb(null, 'ok'); 
 
    }; 
 
};

+2

あなた '.then'呼び出しが(何かを返す必要が' Notifications.isMatching'を返す '、Notifications.execute(sql'を返します...)あなたの 'isMatching'関数i非同期ではないかもしれないが、おそらくあなたのコードを単純化することができるかもしれない。 – arvymetal

+1

このコードは非常に間違っている。まず、もっと簡単なアルゴリズムに取り組んで、約束事で作業することを学ぶべきである(最後に同期コールバック約束を使用する...完全に役に立たない) – trincot

+0

nsynjsを使用してコードを同期的に実行することができます。たとえば、https://github.com/amaksr/nsynjs/tree/master/examples/node-mysqlを参照してください。文の実行。 – amaksr

答えて

0

あなたのコードを持ついくつかの問題があります。

ために
  • チェーンには、約束する、あなたはする必要がありますあなたはthenコールバックあなたは(isMatching

  • 約束は果たしたときにthenコールバックが常に実行され、すぐに利用可能な結果のための約束を作成する必要はありません

  • 以内に作成する約束を返すことを確認してください。 resolve(false)を実行するかどうかは関係ありません。約束された値がfalseであっても、約束が満たされ、thenコールバックがトリガーされます。

あり、あなたのコード内のいくつか未知数Notifications.findのように、ある、とあなたが実行しているSQLの種類:それはそうならば、あなたはその結果を得るために興味があるだけではなく解決しないだろう、結果セットを返しませんブール値?あなたも一緒に始めるとあなたが約束を使用しておく必要がありますので、あなたは、この関数を呼び出すとき:Notifications.getByUserの署名は、最終的なコールバックパラメータを持っていないことを

'use strict'; 
var Promise = require("bluebird"); 

module.exports = function(Notifications) { 
    Notifications.execute = function(sql, itemId) { 
     return new Promise((resolve, reject) => { 
      this.dataSource.connector.execute(sql, (e, result) => { 
       console.log('-----RESULT----', itemId); 
       console.log(result); 
       console.log('-----ERROR-----', itemId); 
       console.log(e); 
       resolve (result.length !== 0); // The `if ... else` is overkill 
      }); 
     }); 
    }; 

    //You don't need isMatching to return a promise 
    Notifications.isMatching = function(a, b) { 
     return a === null || a === b; 
    }; 

    Notifications.getByUser = function(userId, isZolver, countryId, cityId, userState) { 
     var where = { status: 1 }; 
     var items = Notifications.find({ where }) 
      // use filter() to limit the items to those you want to execute the SQL for 
      .filter(item => { 
       return Notifications.isMatching(item.isZolver, isZolver) 
        && Notifications.isMatching(item.cityId, cityId) 
        && item.extraCondition !== '' 
      }); 
     // Return the promise! (don't go back to the old callback system!) 
     return Promise.each(items, item => { 
      var sql = item.extraCondition.replace(/:user_id/g, userId); 
      // Return the promise! 
      return Notifications.execute(sql, item.id); 
     }).then(res => { 
      console.log('res del loop', res); 
     }); 
    }; 
}; 

注:

はとにかく、ここでいくつかの修正を適用していますあなたが任意の約束のために行うだろうと同じように、結果のthenメソッドを呼び出します。

Notifications.getByUser(.......arguments....).then(function() { 
    // do something... 
}); 
+0

あなたの答えはすばらしかったです、ありがとう、私はPHPからの脱走者であり、時々ちょっと複雑ですが信じられないほど興味深いです、それは全く新しい世界です:) – Grunch

+0

あなたを歓迎します;-) – trincot

関連する問題