2017-04-06 119 views
0

我使用Angular的$ q服務返回承諾。在我的函數中,當我通過在一系列圖片中搜索的id(鍵值)找到圖片(對象)時,promise被解析。如果數組爲空,我得到圖片,否則我開始搜索。 該功能正在工作,但我無法將其作爲承諾。

我的服務方法:

picturesService.getCurrentPic = function (pictureId) { 

    console.log("process started, id: ", pictureId); 
    if(picturesService.pictures.length == 0){ 
     console.log("empty"); 
     picturesService.getPictures().then(function(data){ 
      picturesService.pictures = data.data.children; 
      picturesService.getCurrentPic(pictureId); 
     }); 
    }else{ 
     var deferred = $q.defer(); 
     console.log("not empty"); 
     for (var i = picturesService.pictures.length - 1; i >= 0; i--) { 
      if(picturesService.pictures[i].data.id == pictureId){ 
       console.log("found: ", picturesService.pictures[i].data); 
       deferred.resolve(picturesService.pictures[i].data); 
       break; 
      }; 
     }; 
     return deferred.promise; 
    }; 
}; 

控制器代碼:

picturesService.getCurrentPic(vm.pictureId).then(function(data){ 
    vm.currentPic = data; 
    console.log("currentPic: ", vm.currentPic); 
}); 

錯誤,那是我得到:

無法讀取屬性 '然後' 未定義

回答

0

第一條件也必須返回一個承諾。 您還必須在發生錯誤時拒絕承諾:

picturesService.getCurrentPic = function(pictureId) { 

    var deferred = $q.defer(); 

    console.log("process started, id: ", pictureId); 
    if (picturesService.pictures.length == 0) { 
     console.log("empty"); 
     picturesService.getPictures().then(function(data) { 
      picturesService.pictures = data.data.children; 
      return picturesService.getCurrentPic(pictureId); 

     }, function(error) { 
      deferred.reject(error.message || error) 
     }); 
    } else { 
     console.log("not empty"); 
     var picture; 
     for (var i = picturesService.pictures.length - 1; i >= 0; i--) { 
      if (picturesService.pictures[i].data.id == pictureId) { 
       picture = picturesService.pictures[i].data; 
       console.log("found: ", picture); 
       break; 
      }; 
     }; 
     if (picture) { 
      deferred.resolve(picture) 
     } else { 
      deferred.reject('picture not found: ' + id) 
     } 
    }; 

    return deferred.promise; 
}; 

然後使用它像這樣來處理錯誤:

picturesService.getCurrentPic(vm.pictureId).then(function(data){ 
    vm.currentPic = data; 
    console.log("currentPic: ", vm.currentPic); 
}, function(error) { 
    console.log('error occured: ' + error); 
}); 
+0

所以,如果非要用遞歸話,我必須這樣做,用的諾言?另外,如果我不拒絕承諾(同意不是一個好的做法),它應該仍然是正確的? – y13uc162

+0

使用遞歸不是一個好習慣,你應該更好地鏈接承諾:首先加載圖像,然後通過id檢索圖片。不拒絕承諾是一個非常糟糕的主意,不要這樣做^^ –

0

您遞歸調用getCurrentPic內的情況下,當getPictures()返回空數據,這將繼續下去,這不是一個好的設計。我會建議通過分裂承諾並將它們聯繫起來,使事情變得簡單。

對於學習承諾鏈接:http://solutionoptimist.com/2013/12/27/javascript-promise-chains-2/

壓扁承諾鏈接,如果它走出你的手:http://solutionoptimist.com/2013/12/27/javascript-promise-chains-2/

picturesService.pictures = []; 
picturesService.getAllPictures() = function() { 
    console.log('getting all pictures'); 
    picturesService.getPictures().then(function(data){ 
    console.log('populatiing the pictures array'); 
    picturesService.pictures = data.data.children; 
    }); 
} 

picturesService.getCurrentPic = function(pictureId) { 
    var deferred = $q.defer(); 
    console.log('getting the picture information for ', pictureID); 
    for (var i = picturesService.pictures.length - 1; i >= 0; i--) { 
    if(picturesService.pictures[i].data.id == pictureId) { 
     console.log("found: ", picturesService.pictures[i].data); 
     deferred.resolve(picturesService.pictures[i].data); 
    }; 
    }; 
    return deferred.promise; 
} 

// controller code 
picturesService.getAllPictures().then(function() { 
    picturesService.getCurrentPic(vm.pictureId).then(function(data){ 
     vm.currentPic = data; 
     console.log("currentPic: ", vm.currentPic); 
    }); 
});