简体   繁体   English

如何避免异步javascript中的冗余代码?

[英]How to avoid redundant code in asynchronous javascript?

I'm rewriting some database code from synchronous (LocalStorage) to asynchronous (IndexedDB). 我正在将一些数据库代码从同步(LocalStorage)重写为异步(IndexedDB)。 I'm using the Alasql library and Promises. 我正在使用Alasql库和Promises。 One of the problems I encounter is that when doing things asynchronously, sometimes it seems impossible to avoid duplicating code. 我遇到的问题之一是异步执行操作时,有时似乎不可避免地避免了重复代码。

For example, my synchronous (pseudo) code could be something like this (idExists, doUpdate and doInsert are database methods): 例如,我的同步(伪)代码可能是这样的(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);
}

With asynchronous code, it becomes something like this: 使用异步代码,它会变成这样:

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);
            });
        }
    });
}

Here I have to call doSomething at two places in the code. 在这里,我必须在代码的两个地方调用doSomething Is there a way to avoid this situation? 有办法避免这种情况吗? I'm new to promises and my apologies if this has been asked before, but I couldn't find an answer to this. 如果以前曾问过这个问题,我对诺言和道歉还是陌生的,但是我找不到答案。

You can return a promise from a chained callback, which then gets inserted into the promise chain. 您可以从链接的回调中return承诺,然后将其插入到承诺链中。 Your code can, and should, be written as: 您的代码可以并且应该被编写为:

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

The promises from doInsert or doUpdate will be chained into the existing chain from idExists , so the final .then(doSomething) will be executed with their result. doInsertdoUpdate doInsert将被链接到idExists的现有链中,因此最终的idExists .then(doSomething)将与它们的结果一起执行。

You can store promise into variable and call doSomething only once: 您可以将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)
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM