2017-04-20 71 views
2

我正在從同步(LocalStorage)重寫一些數據庫代碼爲異步(IndexedDB)。我正在使用Alasql庫和Promises。我遇到的一個問題是,當異步執行時,有時似乎不可能避免重複代碼。如何避免異步JavaScript中的冗餘代碼?

例如,我的同步(僞)代碼可能是這樣的(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。有沒有辦法避免這種情況?如果以前有人問過我,我對承諾和新的道歉是新的,但是我找不到答案。

回答

2

您可以return從鏈回調,然後把它插入到諾言鏈的承諾。你的代碼可以,而且應該寫成:

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

doInsertdoUpdate的承諾將被鏈接到現有鏈從idExists,所以最終.then(doSomething)將他們的結果來執行。

+0

美麗(現在看來我明白了......)。謝謝你,先生! –

1

您可以存儲到承諾變量,並調用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) 
    }); 
} 
+0

很好的答案,但我認爲欺騙你擊敗了它。 :) 不管怎麼說,還是要謝謝你! –

+0

是的,他的回答是更好的:) – dfsq