在JavaScript中重构嵌套if语句

Refactoring nested if statements in JavaScript

本文关键字:if 语句 嵌套 重构 JavaScript      更新时间:2023-09-26

我有一长串嵌套的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 {
                        ...
                    }
                });
            }
        });
    }
});

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

下面的代码在逻辑上等同于上面的代码。

// 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.
    }
}