循环

时间:2017-05-29 21:52:07

标签: javascript node.js promise bluebird

我知道这是一个有很多信息的话题,但我仍然无法解决这个问题。

我正在使用连接到mysql服务器的NodeJs,我有一个数组,我需要迭代数组并对数据做一些事情,事情是我需要对mysql服务器进行查询但我需要到for循环等到我得到了查询的结果,我已经尝试了很多东西,现在我正在尝试使用bluebird的.each方法,但仍然无法正常工作,这是我的代码。

初始函数是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');
  };
};

1 个答案:

答案 0 :(得分:0)

您的代码存在以下问题:

  • 为了实现承诺链接,您必须确保返回在then回调中创建的承诺

  • 您不需要为可立即获得的结果创建承诺(isMatching

  • 当承诺履行时,始终执行then回调。您是否resolve(false)无关紧要:即使承诺的值为false,这仍然会使承诺得到满足并触发then回调。

您的代码中有一些未知数,例如Notifications.find,以及您正在执行的SQL类型:它是否返回结果集,如果是,您是否有兴趣获得该结果而不仅仅是解析一个布尔值?

无论如何,这里有一些应用的更正:

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

请注意Notifications.getByUser的签名没有最终的回调参数:一旦你开始使用它们就应该继续使用promises,所以当你调用这个函数时,像你一样调用结果的then方法会做任何承诺:

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