【问题标题】:Refactoring nested if statements in JavaScript重构 JavaScript 中的嵌套 if 语句
【发布时间】:2015-11-13 14:30:36
【问题描述】:

我有一长串嵌套的 if 语句。我编写的代码运行良好,但非常笨拙。有没有更简单的写法?

couchdb.query(phoneParam, function(err, data) {
    if (err) {
        console.log(err, err.stack);
    } else if (data.Items.length > 0) {
        deferred.resolve(data.Items[0]);
    } else {
        couchdb.query(phone1Param, function(err, data) {
            if (err) {
                console.log(err, err.stack);
            } else if (data.Items.length > 0) {
                deferred.resolve(data.Items[0]);
            } else {
                couchdb.query(phone2Param, function(err, data) {
                    if (err) {
                        console.log(err, err.stack);
                    } else if (data.Items.length > 0) {
                        deferred.resolve(data.Items[0]);
                    } else {
                        ...
                    }
                });
            }
        });
    }
});

【问题讨论】:

  • 我发现嵌套函数比嵌套 ifs 更笨拙。
  • 我同意,有没有更好的方法不嵌套函数?
  • 是 pouchdb/couchdb 吗?
  • 一次尝试/捕获将巩固您的错误捕获。在函数开始时验证您的参数将使此代码更具可读性。
  • 这是沙发数据库。代码有效,我只是想做得更好。错误消息来自我的服务器。有没有办法用 try/catch 做到这一点?

标签: javascript refactoring


【解决方案1】:

如果查询没有产生任何有趣的结果,您可以通过编写一个将自身传递给couchdb.query 的回调函数来替换嵌套的条件。要使新查询使用下一个 phone 参数,请增加一个变量,该变量充当 phone 参数数组的索引。

下面的代码在逻辑上等价于你上面写的。

// Put all of your phone parameters into an array.
var phoneParams = [phoneParam, phone1Param, phone2Param, phone3Param]; 

// Use pos to track the array position of the current parameter.
var pos = 0;

function callback(err, data) {
    if (err) { 
        console.log(err, err.stack);
    } else if (data.Items.length > 0) { 
        deferred.resolve(data.Items[0]);
    } else if (++pos < phoneParams.length) {        // Increment the array position.
        couchdb.query(phoneParams[pos], callback);  // Recursive use of callback.
    }
}

// Kick off the series of calls.
couchdb.query(phoneParams[pos], callback);

之后检查pos 的值可能是个好主意。如果它等于phoneParams.length,您就知道没有任何电话参数被淘汰,您可以对此做点什么。你究竟会把这段代码放在哪里?您不能只在初始调用 couchdb.query 之后插入它,因为它是异步的,您不知道最终回调何时完成。

解决方案是在另一个函数中继续您的代码。您可以在从callback 退出时调用该函数而无需递归。例如,如果包含清理代码的函数称为finish,则可以修改callback,如下:

function callback(err, data) {
    if (err) {                                // Print error and finish.
        console.log(err, err.stack);
        finish();
    } else if (data.Items.length > 0) {       // Use data and finish.
        deferred.resolve(data.Items[0]);
        finish();
    } else if (++pos < phoneParams.length) {  // Don't finish -- recurse.
        couchdb.query(phoneParams[pos], callback);
    } else {
      finish();                               // No choice but to finish.
    }
}

【讨论】:

  • 请看我修改后的答案。它甚至更短,现在可以正常处理异步查询。
  • 我想过做这样的事情,但它不会为 phoneParams 数组中的每个项目发送一个查询吗?
  • 不一定。请注意,递归调用仅在没有错误且没有数据项的情况下发生。一旦您收到错误或数据项,该函数就会处理它并返回。递归调用是最后的手段。
猜你喜欢
  • 2020-01-02
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
相关资源
最近更新 更多