I'm rewriting some database code from synchronous (LocalStorage) to asynchronous (IndexedDB). I'm using the Alasql library and 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):
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. 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. 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.