2013-01-22 24 views
0

我有項目的ID在頁面加載列表:如何選擇使用承諾仍然加載的項目?

var itemIds = [1, 5, 10, 11]; 

ID被渲染成列表,並顯示給用戶。我有加載關於物品的詳細信息的功能,它返回Promise/A。

function loadInfo(id) { ... } 

所有項目信息的加載開始在頁面加載:

val infos = {}; 
$.each(itemIds, function(i, id) { infos[id] = loadInfo(id); } 

現在的問題本身。

當用戶點擊項ID:

  • 如果項目信息被加載,信息必須顯示
  • 如果項目信息還沒有加載,則必須在它被加載
顯示

看起來很容易:

$('li').click(function() { 
    var id = $(this).data('item-id'); 
    infos[id].then(function(info) { $('#info').text(info); }); 
}); 

但是,如果用戶cliked當前一個之前的另一個項目被加載時, n我必須取消當前項目承諾的處理程序並安排新程序。

如何正確地做到這一點?

我有幾個工作解決方案(如維護currentItemId變量並在promise處理程序中檢查它),但它們很醜陋。我應該看看反應式編程庫嗎?

回答

0

Kriomant,

我想有一些,你可以編寫這樣的方式。這裏有一個:

var INFOS = (function(){ 
    var infoCache = {}, 
     promises = {}, 
     fetching = null; 

    var load = function(id) { 
     if(!promises[id]) { 
      promises[id] = $ajax({ 
       //ajax options here 
      }).done(function(info){ 
       infoCache[id] = info; 
       delete promises[id]; 
      }); 
     } 
     return promises[id]; 
    } 

    var display = function(id, $container) { 
     if(fetching) { 
      //cancel display (but not loading) of anything latent. 
      fetching.reject(); 
     } 
     if(infoCache[id]) { 
      //info is already cached, so simply display it. 
      $container.text(infoCache[id]); 
     } 
     else { 
      fetching = $.Deferred().done(function() { 
       $container.text(infoCache[id]); 
      }); 
      load(id).done(fetching.resolve); 
     } 
    } 
    return { 
     load: load, 
     display: display 
    }; 
})(); 

正如你所看到的,所有的複雜性在命名空間INFOS,暴露兩個方法捆綁; loaddisplay

下面是如何調用的方法:

$(function() { 
    itemIds = ["p7", "p8", "p9"]; 

    //preload 
    $.each(itemIds, function(i, id) { INFOS.load(id); }); 

    //load into cache on first click, then display from cache. 
    $('li').on('click', function() { 
     var id = $(this).data('item-id'); 
     INFOS.display(id, $('#info')); 
    }); 
}); 

DEMO(帶模擬AJAX)

這裏的技巧是:

  • 緩存的相關信息,通過ID
  • 索引
  • 來緩存有效的jqXHR承諾,索引編號爲
  • 如果之前已加載,則顯示來自緩存的信息...
  • ...否則,每次請求信息時,創建一個與信息顯示相關聯的延遲,可以獨立於相應的jqXHR解析/拒絕。
+0

好的,這個解決方案實際上與我使用的相似,正如我所說的那樣,它很醜陋。但是,由於這是唯一的答案,並且技術上正確,我接受它。 – kriomant

+0

也許有人會遇到一些不那麼「醜陋」的東西,但是和我一樣,他們可能會在這一點上與定義發生衝突。醜陋就像美麗 - 它在旁觀者的眼中。 –

相關問題