2016-04-24 54 views
5

假設我有一個同步函數,如path.join()。我想將其包裝到Promise因爲我想要在catch()區塊內處理優先事項。 如果我換成下面的樣子,我不能在Promise.catch()區塊發生異常。所以我必須使用if來檢查返回值,如果它是錯誤的,然後調用resolve,reject函數。還有其他解決方案嗎?將同步函數包裝到承諾中的最佳方式是什麼

var joinPaths = function(path1,path2) { 
    return new promise(function (resolve, reject) { 
    resolve(path.join(path1, path2)); 
    }); 
}; 
+2

爲什麼要將同步函數包裝爲承諾? –

+1

當需要用硬編碼值替換一些異步調用時,單元測試是一種常見情況 –

+1

將同步函數包裝爲承諾的最佳方式不是這樣做。 – Bergi

回答

6

目前還不清楚爲什麼你會在一個承諾包的同步操作,只是使之更難以用和同步操作已經可以承諾鏈就好內使用。

我認爲只有兩個地方用它來實現某種同步的承諾非常有用,那就是啓動一個承諾鏈,其中後續操作將是異步的,或者當您分支時,並且分支的一個結果是異步承諾,其他是同步的。然後,在這種情況下,您只需要在兩種情況下都返回一個承諾,以便調用方擁有一致的異步接口,而不管採用哪個分支。

除此之外,你通常不應該使同步的東西異步,因爲它只是不必要地複雜使用它們。

我知道的最簡單的方法,使之變成一個承諾會是這樣:

Promise.resolve(path.join(path1, path2)).then(function(path) { 
    // use the result here 
}); 

根據您的意見,一個.then()處理器中,異常已經被承諾的基礎設施捕獲並變成了拒絕承諾。所以,如果你有這個:

someAsyncOp().then(function(value) { 
    // some other stuff 
    // something that causes an exception 
    throw new Error("timeout"); 
}).catch(function(err){ 
    console.log(err); // will show timeout 
}); 

然後,那個例外已經映射到你的承諾拒絕。當然,如果你想處理.then()處理程序中的異常(而不是將承諾變爲拒絕),那麼你可以在同步操作周圍使用傳統的try/catch來捕獲本地異常(與其他任何異常無異)同步代碼)。但是,如果您希望承諾在.then()處理程序中存在異常時拒絕,那麼這些都是自動完成的(這是一個非常好的承諾功能)。

+0

如果我在承諾鏈中使用'path.join',並且想處理''''.catch()'塊中的異常,我該怎麼做把它包裝在承諾中? – CoderS

+2

@Srinesh - 與往常一樣,如果您將實際代碼和實際問題置於您的問題中,我們可以爲您提供更好的幫助。我並不完全按照你所要做的。承諾鏈中的'.then()'處理程序已經包裝在try/catch中,並且在'.then()'處理程序中拋出的任何異常都會自動拒絕承諾鏈。你不必爲了在'.then()'處理程序中獲得該功能而做任何事情。您也可以使用try/catch來捕獲同步異常並在本地處理它。 – jfriend00

+1

爲什麼你可能想在一個promise中包裝一個同步函數的一個原因是,如果你試圖堅持一個契約,即'if(needsUpdating){return object.asyncUpdate(); } else {return object};'如果一個路徑返回一個Promise,那麼其他路徑也應該如此,即使它沒有運行任何異步代碼。 –

相關問題