使用$q服务使函数返回 deferred.promise,但它返回未定义



>我正在使用Angular的$q服务来返回承诺。在我的函数中,当我通过我在图片数组中搜索的 id(键值(找到图片(对象(时,承诺就会得到解决。如果数组为空,我会得到图片,否则我开始搜索。该功能正在工作,但我无法将其变成承诺。

我的服务方式:

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);
});

我收到的错误:

无法读取未定义的属性"then">

第一个条件也必须返回一个承诺。发生错误时,您还必须拒绝承诺:

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);
});

你在里面递归地调用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);
    });
});

最新更新