【问题标题】:How to avoid redundant code in asynchronous javascript?如何避免异步javascript中的冗余代码?
【发布时间】:2025-12-07 12:40:01
【问题描述】:

我正在将一些数据库代码从同步 (LocalStorage) 重写为异步 (IndexedDB)。我正在使用 Alasql 库和 Promises。我遇到的一个问题是,在异步做事时,有时似乎无法避免重复代码。

例如,我的同步(伪)代码可能是这样的(idExists、doUpdate 和 doInsert 是数据库方法):

function insertOrUpdate(data,id)
{
    var result = null;
    if (!idExists(id)) // idExists returns a boolean
        result = doInsert(data,id); // doInsert returns an object
    else
        result = doUpdate(data,id); // doUpdate returns an object
    doSomething(result);
}

使用异步代码,它变成了这样:

function insertOrUpdate(data,id)
{
    var promise1 = idExists(id); // idExists returns a promise
    promise1.then( function(id_exists) {
        if (id_exists) {
            var promise2 = doInsert(data,id); // doInsert returns a promise
            promise2.then( function(result) {
                doSomething(result);
            });
        }
        else {
            var promise3 = doUpdate(data,id); // doUpdate returns a promise
            promise3.then( function(result) {
                doSomething(result);
            });
        }
    });
}

这里我必须在代码中的两个地方调用doSomething。有没有办法避免这种情况?如果以前有人问过这个问题,我是新来的,我很抱歉,但我找不到答案。

【问题讨论】:

    标签: javascript asynchronous promise indexeddb alasql


    【解决方案1】:

    您可以将 promise 存储到变量中,并且只调用一次 doSomething:

    function insertOrUpdate(data, id) {
      return idExists(id).then(function(id_exists) {
        var promise = id_exists ? doInsert(data, id) : doUpdate(data, id)
        return promise.then(doSomething)
      });
    }
    

    【讨论】:

    • 很好的答案,但我认为 deceze 打败了你。 :) 还是谢谢!
    【解决方案2】:

    您可以return 来自链式回调的承诺,然后将其插入到承诺链中。你的代码可以而且应该写成:

    function insertOrUpdate(data, id) {
        return idExists(id)
            .then(function (exists) {
                return exists ? doInsert(data, id) : doUpdate(data, id);
            })
            .then(doSomething);
    }
    

    来自doInsertdoUpdate 的promise 将被链接到来自idExists 的现有链中,因此最终的.then(doSomething) 将与它们的结果一起执行。

    【讨论】:

    • 美丽(现在我看到它很明显......)。谢谢楼主!