多个if,else if语句中的回调地狱

时间:2017-02-20 14:24:36

标签: javascript node.js

我可以使用数据回调参数。 数据是一个具有许多属性的对象,我必须验证这些属性。我写了多个if,else if语句来做,但对我来说似乎很恶心。

function(data, callback) {

 if (data.a != 'x') {
   logger.log(...);
   return callback({status: false, code: 'x'});
 } else if (data.b != 'y') {
   logger.log(...);
   return callback({status: false, code: 'y'});
 } else if (data.c != 'z') {
   logger.log(...);
   return callback({status: false, code: 'z'});
 } else if (data.d != 'w') {
   logger.log(...);
   return callback({status: false, code: 'w'});
 }

 //... logic ...
 return callback({status: true});
}

我认为这不适合这样做。

5 个答案:

答案 0 :(得分:6)

一种方法是将验证分解为一个单独的函数:

function failureCode(data) {
    if (data.a != 'x')
        return 'x';
    if (data.b != 'y')
        return 'y';
    if (data.c != 'z')
        return 'z';
}

function (data, callback) {
    var code = failureCode(data);
    if (code) {
        logger.log(...);
        return callback({status: false, code: code});
    }

    //... logic ...
}

另外,请不要忘记{"失败&#34}中的return分支。

答案 1 :(得分:1)

这个怎么样?因为您实际上正在进行验证和提交"你可以抛出代码并捕获结果。

function(data, callback) {
    try {
         if (data.a != 'x') {
             throw 'x';
         }

         if (data.b != 'y') {
             throw 'y';
         }

         // etc

         // logic

         callback({status: true});
    }
    catch(code) {
        callback({status: false, code: code});
    }
}

答案 2 :(得分:1)

因为看起来代码是正确的,但需要赏心悦目,这里有你可以尝试的东西:

function(data, callback) {

  var code;

  if (data.a != 'x') code = 'x';
  else if (data.b != 'y') code = 'y';
  else if (data.c != 'z') code = 'z';
  else if (data.d != 'w') code = 'w';

  if (code) {
    callback({ status: false, code: code });
  } else {
    callback({ status: true });
  }
}

如果比较事先已知,那么:

function(data, callback) {

  var code,

    comparisons = [{
      key: 'a',
      val: 'x'
    }, {
      key: 'b',
      val: 'y'
    }, {
      key: 'c',
      val: 'z'
    }, {
      key: 'd',
      val: 'w'
    }];

  for (each of comparisons) {

    if (data[each.key] != each.val) {
      code = each.val;
      break;
    }
  }

  if (code) {
    callback({ status: false, code: code });
  } else {
    callback({ status: true });
  }
}

答案 3 :(得分:1)

没有简单的方法可以做到这一点,因为您正在从数据的不同领域阅读,并使用不等式。如果您正在使用相同的数据键(称为code),则可以在惯用的javascript中执行以下操作:

function (data, callback) {
  switch(data.code) {
      case 'x':
          logger.log(...);
          callback({status: false, code: 'x'});
          break;
      case 'y':
          logger.log(...);
          callback({status: false, code: 'y'});
          break;
      case 'z':
          logger.log(...);
          callback({status: false, code: 'z'});
          break;
      case 'w':
          logger.log(...);
          callback({status: false, code: 'w'});
          break;
      default:
          callback({status: true})
   }
}

请注意,switch语句实际上与原始功能完全不同。首先,它是一个关于价值的真实断言,每次运行只会产生一个分支。例如。在原始代码中,如果数据是这样的对象:

const data = {a: 'a', b: 'b', c: 'c', d: 'd'}每个分支都会运行,而在交换机实现中,只运行默认分支。在任何一种情况下,我都鼓励您将解决方案重新构建为易于推理的形状,以适合交换机。

如果您可以使用ES6语法/对象解构,您可以使用像babel这样的转换程序连接您的项目,并且仍然使用多个键,如您的原始实现,以执行以下操作

function ({a, b, c, d}, callback) {
  if (a != 'x') {
    logger.log(...);
    callback({status: false, code: 'x'});
  } else if (b != 'y') {
    logger.log(...);
    callback({status: false, code: 'y'});
  } else if (c != 'z') {
    logger.log(...);
    callback({status: false, code: 'z'});
  } else if (d != 'w') {
    logger.log(...);
    callback({status: false, code: 'w'});
  }

  //... logic ...
  callback({status: true});
}

通过更多预配置,您可以执行以下操作:

const keys = ['a', 'b', 'c', 'd']
const codes = {'a': 'x', 'b': 'y', 'c': 'z', 'd': 'w'}

您的功能现在可以是:

function(data, callback) {
  keys.map(function(key) {
    if (data[key] != codes[key]) {
      logger.log(...);
      callback({status: false, code: codes[key]});
    }})
    //logic
    callback({status: true})
    }

请注意,如果您愿意,可以将codemap / keylist作为函数参数传递

答案 4 :(得分:0)

我会在验证例程中包含一组预期值:

function(data, expected, callback) {
  var checkProp = function(prop) {
    return (data[prop] === expected[prop]);
  };

  for (var p in data) {
    if (data.hasOwnProperty(p)) {
      if (!checkProp(p)) {
        callback({status: false, code: expected[p]});
        return;
      }
    }
  }
  callback({status: true});
}

所以,例如,如果我有一个对象:

{ a: 1, b: 2}

我可能会包含expected这样的参数:

{ a: 3, b: 4 }

这是一个有效的演示:



function validate(data, expected, callback) {
  var checkProp = function(prop) {
    return (data[prop] === expected[prop]);
  };

  for (var p in data) {
    if (data.hasOwnProperty(p)) {
      if (!checkProp(p)) {
        callback({status: false, code: expected[p]});
        return;
      }
    }
  }
  callback({status: true});
}

var obj = { a: 1, b: 2 },
  expected = { a: 1, b: 4 };
validate(obj, expected, function(res) {
  if (!res.status) {
    console.log('failed with value ' + res.code);
  } else {
    console.log('success');
  }
});