NodeJs:等待ForEach功能

时间:2015-12-03 10:03:43

标签: javascript node.js

我写了一个验证函数,我想检查一个数组是否有效。我想要返回多个错误。 我搜索了那个主题,但无法使用promise,async-module运行它。 我对NodeJS很新,如果你能帮助我,我将非常感激。

function validateNewResultUnits(sets, req) {
  var validate = [];
  sets.forEach(function(setItem) {
    setItem.forEach(function(item) {
      if (item.hasOwnProperty("name") == false) {
        validate.push({
          'name': 'Name has to be set'
        });
      } else {
        if (item.name === "" || item.name === null || item.name === undefined) {
          validate.push({
            'name': 'Name cannot be empty'
          });
        } else {
          Exercise.forge({
            name: req.body.name
          }).fetch({
            withRelated: [{
              'resultUnits': function(qb) {
                qb.where('name', item.name);
              }
            }]
          }).then(function(exercise) {
            console.log("Länge:" + exercise.related('resultUnits').length);
            if (exercise.related('resultUnits').length === 0)
              validate.push({
                'name': 'ResultUnit not found'
              });
          }).catch(function(error) {
            validate.push({
              'name': 'An Error occured'
            });
          });
        }
      }

      if (item.hasOwnProperty("value") == false) {
        validate.push({
          'value': 'Value has to be set'
        });
      } else {
        if (item.value === "" || item.value === null || item.value === undefined) {
          validate.push({
            'value': 'Name cannot be empty'
          });
        } else {
          if (isNaN(item.value)) validate.push({
            'value': 'Value has to be number'
          });
        }
      }
    });
  });
  return validate;
}

var validate = validateNewResultUnits(req.body.sets, req);
console.log(validate);
if (validate.length == 0) {
  // ...
}

在函数准备返回某些内容之前,console.log(validate);返回undefined。 非常感谢。

编辑: 承诺尝试(在第二个forEach内)

var promise = new Promise(function(resolve) {
                                Exercise.forge({name: req.body.name })
                                .fetch({
                                    withRelated: [{'resultUnits': function(qb) {
                                        qb.where('name',item.name)
                                    }}]
                                }).then(function(exercise) { 
                                console.log("Länge:"+exercise.related('resultUnits').length);
                                if (exercise.related('resultUnits').length === 0)
                                    resolve({'name':'ResultUnit not found'});
                                }).catch(function(error) { resolve({'name': 'An Error occured'}); });
                            });
                            promise.then(function(result) {
                                validate.push(result);
                            });

1 个答案:

答案 0 :(得分:3)

问题出在Exercise.forge({name: req.body.name }).fetch(...),因为它以异步方式运行,这使得validateNewResultUnits函数继续执行,直到返回未定义的结果。

我建议您更改代码以包含promises而不是那些丑陋的异步回调,这需要更改validateNewResultUnits函数本身及其任何调用者。以下是一些可以帮助您快速了解承诺的资源:

https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

Understanding promises in node.js

http://howtonode.org/promises

https://vimeo.com/144550711

https://vimeo.com/144550811

https://vimeo.com/144550913

修改

以下是提供的代码的副本,但使用promises代替

function validateNewResultUnits(sets, req) {
  return new Promise(function(resolve, reject){
    var validate = [];
    var internalPromises = [];
    sets.forEach(function(setItem) {
      setItem.forEach(function(item) {
        if (item.hasOwnProperty("name") == false) {
          validate.push({'name': 'Name has to be set'});
        } else {
          if (item.name === "" || item.name === null || item.name === undefined) {
            validate.push({'name': 'Name cannot be empty'});
          } else {
            var internalPromise = Exercise.forge({name: req.body.name}).fetch({
                withRelated: [{
                  'resultUnits': function (qb) {
                    qb.where('name', item.name);
                  }
                }]
              });
            internalPromise.then(function(exercise) {
              console.log("Länge:" + exercise.related('resultUnits').length);
              if (exercise.related('resultUnits').length === 0)
                validate.push({'name': 'ResultUnit not found'});
            }).catch(function(error) {
              validate.push({'name': 'An Error occured'});
            });
            internalPromises.push(internalPromise);
          }
        }

        if (item.hasOwnProperty("value") == false) {
          validate.push({'value': 'Value has to be set'});
        } else {
          if (item.value === "" || item.value === null || item.value === undefined) {
            validate.push({'value': 'Name cannot be empty'});
          } else {
            if (isNaN(item.value))
              validate.push({'value': 'Value has to be number'});
          }
        }
      });
    });

    if(internalPromises && internalPromises.length) {
      Promise.all(internalPromises).then(function (value) {
        console.log(value);
        resolve(validate);
      }, function (reason) {
        console.log(reason);
        resolve(validate);
      });
    } else {
      resolve(validate);
    }
  });
}

var validatePromise = validateNewResultUnits(req.body.sets, req);
validatePromise.then(function(result){
  console.log(result);
  if (result.length == 0) {
    // ...
  }
});