如何避免异步javascript中的冗余代码?
How to avoid redundant code in asynchronous javascript?
我正在将一些数据库代码从同步 (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
。有没有办法避免这种情况?我是 promises 的新手,如果之前有人问过这个问题,我深表歉意,但我找不到答案。
您可以将 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)
});
}
您可以 return
来自链式回调的承诺,然后将其插入到承诺链中。您的代码可以而且应该写成:
function insertOrUpdate(data, id) {
return idExists(id)
.then(function (exists) {
return exists ? doInsert(data, id) : doUpdate(data, id);
})
.then(doSomething);
}
来自 doInsert
或 doUpdate
的承诺将链接到来自 idExists
的现有链中,因此最终的 .then(doSomething)
将使用它们的结果执行。
我正在将一些数据库代码从同步 (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
。有没有办法避免这种情况?我是 promises 的新手,如果之前有人问过这个问题,我深表歉意,但我找不到答案。
您可以将 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)
});
}
您可以 return
来自链式回调的承诺,然后将其插入到承诺链中。您的代码可以而且应该写成:
function insertOrUpdate(data, id) {
return idExists(id)
.then(function (exists) {
return exists ? doInsert(data, id) : doUpdate(data, id);
})
.then(doSomething);
}
来自 doInsert
或 doUpdate
的承诺将链接到来自 idExists
的现有链中,因此最终的 .then(doSomething)
将使用它们的结果执行。