2015-11-14 54 views
3

我想要對象請求JavaScript承諾,但我不希望它們創建單獨的承諾。我想要達到的邏輯如下 - 檢查一個承諾是否有待處理,只有沒有,纔會創建一個新的承諾。這可能嗎?根據文檔,我無法檢查承諾的狀態,我只能在完成填充後處理它,但我不想爲每個承諾請求調用處理程序,並且如果一個Promise的回調可以運行,我不希望運行多個Promise迴應所有過去的請求...JavaScript - 對多個請求只運行一個Promise

我試圖解決這個問題的方法是從外部服務器獲取數據並通過事件將其廣播到多個對象後收到它。

+1

如果您更詳細地描述你試圖解決實際問題(包括對您的代碼兩個操作),而不是描述你自己的解決方案(參見[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)),我們可以告訴你如何正確使用promise來處理它。 – jfriend00

+1

@ jfriend00在這種模式適用的情況下有很多用例,並且不是XY問題:例如,多位代碼執行相同的請求,並且您不想爲每個請求啓動新的請求,但也不會想要緩存值,因爲它可能會改變。 –

+0

@BenjaminGruenbaum - 你猜測OP要什麼,你只能爲你的猜測提供一個通用的解決方案。如果OP提供了他們的實際問題和他們實際代碼的例子,我們不必猜測他們正在嘗試做什麼,並且可以提供更多更具體的答案。我建議OP如何讓他們的問題成爲一個更好的問題,這將會提供更具體的答案,而不需要猜測他們想要什麼。你可能猜對了,我真的不確定。但是,任何需要猜測的問題都可能會更好。 – jfriend00

回答

4

當然,這是很容易做到

var _p = null; // just a cache 
function batchRequests(fn){ 
    if(_p != null) return _p; // if we have an in-flight request, return it 
    _p = fn(); // otherwise start a new action 
    _p.then(function(){ _p = null; }, // delete cache on resolve 
      function(){ _p = null; }); // even on failure 
    return _p; // return the new in-flight request 
} 

它可以讓你做的事:

function delay(){ // just for example, simulate a request 
    return new Promise(function(resolve){ setTimeout(resolve, 1000); }); 
} 

var batched = function(){ return batchRequests(delay); }; 
batched().then(function(){ console.log("All these"); }); 
batched().then(function(){ console.log("execute after"); });  
batched().then(function(){ console.log("one second, at the same time"); }); 
+0

多線程可以成爲一個問題嗎? (對不起,如果這是一個愚蠢的問題,我是JavaScript新手,我不確定這些異步函數是如何工作的,但理論上我們可以在batchRequests中有多個線程,它們檢查全局變量沒有任何承諾,然後每個線程都有他自己的承諾......) – qiubit

+1

簡而言之 - 沒有深度 - 可能不是,除非您在Rhino中運行它,或者作爲另一個lanugage中的嵌入式語言並從該環境中繼承多線程問題。所以「不」適用於大多數環境(瀏覽器,節點等)。 –

+0

不應該是:batched.then(....,而不是批處理()。然後(....? –