2013-11-09 56 views
2

我正在編寫基於$ .getJSON()和HTML5的sessionStorage作爲緩存的基本存儲庫。如何從另一個承諾制定jQuery承諾

當第一次請求數據時,存儲庫將從Web服務讀取數據並將其存儲在sessionStorage中,以便下次從緩存中讀取數據。以下是我的資料庫與任務實體工作代碼:

Storage.prototype.setObject = function (key, value) { this.setItem(key, JSON.stringify(value)); }; 
Storage.prototype.getObject = function (key) { return JSON.parse(this.getItem(key)); }; 

var repository = function() { 
    var getTasks = function() { 
     if (sessionStorage.getObject("Tasks") { 
      return $.Deferred().resolve(sessionStorage.getObject("Tasks")).promise(); 
     } 
     else { 
      return $.getJSON("/gettasks").done(function (data) { 
       sessionStorage.setObject("Tasks", data); 
      }).promise(); 
     } 
    } 

    var findTask = function (id) { 
     var item; 
     return getTasks().done(function (tasks) { 
      for(var t in tasks) 
       if(tasks[t].id == id) 
        item = tasks[t]; 
     }).resolve(item); 
    } 

    return { 
     getTasks: function() { return getTasks(); }, 
     findTask: function (id) { return findTask(id); } 
    }; 
}(); 

getTasks返回類型是一個jQuery承諾反正(數據是從Web服務或從緩存中讀取)。這裏是倉庫的在我的客戶端代碼的用法:

repository.getTasks().done(function (tasks) { 
    // display list 
}).fail(function(err) { 
    // show error 
}); 

現在我要的是通過相同的方式,通過其ID查找任務的另一個功能。所以我需要findTask函數調用getTasks函數,然後嘗試通過id找到列表中的任務項。我的問題是現在返回承諾中的單個任務項目。但find方法現在返回整個列表(基本上它返回getTasks函數的結果)。但我需要它,就像我讀取如下列表一樣:

repository.findTask(765).done(function (task) { 
    // display task item 765 
}).fail(function(err) { 
    // show error 
}); 

非常感謝。

回答

1

使用try deferred.then

var findTask = function (id) { 
    return getTasks().then(function (tasks) { 
     for (var t in tasks) { 
      if (tasks[t].id == id) { 
       return tasks[t]; 
      } 
     } 
    }) 
} 

演示:Fiddle

注:即使該項目未找到做回調將調用該方法的一個問題是。

另一個解決方案是創建自己的遞延像

var findTask = function (id) { 
    var deferred= jQuery.Deferred(); 
    getTasks().done(function (tasks, status, xhr) { 
     for (var t in tasks) { 
      if (tasks[t].id == id) { 
       deferred.resolveWith(this, [tasks[t]]); 
       return; 
      } 
      deferred.reject(xhr, 'error', 'NOT FOUND'); 
     } 
    }).fail(function(xhr, status, textStatus){ 
     deferred.reject.apply(deferred, arguments); 
    }); 

    return deferred.promise(); 
} 

演示:Fiddle

+0

非常感謝。是*然後*工作。我會找出完成回調的方法。再次感謝對不起,我沒有足夠的聲望投票:( – hamid

+0

@ user2971645也看到更新 –