你可以在返回之前解决angularjs的承诺吗?

Cra*_*ste 122 promise angularjs

我正在尝试编写一个返回promise的函数.但有时候请求的信息是立即可用的.我想将它包装在一个承诺中,以便消费者不需要做出决定.

function getSomething(id) {
    if (Cache[id]) {
        var deferred = $q.defer();
        deferred.resolve(Cache[id]); // <-- Can I do this?
        return deferred.promise;
    } else {
        return $http.get('/someUrl', {id:id});
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

somethingService.getSomething(5).then(function(thing) {
    alert(thing);
});
Run Code Online (Sandbox Code Playgroud)

问题是回调不会针对预解析的承诺执行.这是合法的事吗?有没有更好的方法来处理这种情况?

h.c*_*tes 173

简短的回答:是的,您可以在返回之前解决AngularJS承诺,并且它会按照您的预期运行.

来自JB Nizet的Plunkr,但重构在原始问题(即函数调用服务)的环境中工作,实际上是在现场.

服务内...

function getSomething(id) {
    // There will always be a promise so always declare it.
    var deferred = $q.defer();
    if (Cache[id]) {
        // Resolve the deferred $q object before returning the promise
        deferred.resolve(Cache[id]); 
        return deferred.promise;
    } 
    // else- not in cache 
    $http.get('/someUrl', {id:id}).success(function(data){
        // Store your data or what ever.... 
        // Then resolve
        deferred.resolve(data);               
    }).error(function(data, status, headers, config) {
        deferred.reject("Error: request returned status " + status); 
    });
    return deferred.promise;

}
Run Code Online (Sandbox Code Playgroud)

控制器内部....

somethingService.getSomething(5).then(    
    function(thing) {     // On success
        alert(thing);
    },
    function(message) {   // On failure
        alert(message);
    }
);
Run Code Online (Sandbox Code Playgroud)

我希望它对某人有帮助.我没有发现其他答案非常明确.

  • 所以这篇文章的tl; dr是:**是的,你可以在返回之前解决一个承诺,它会按预期短路.** (5认同)
  • 我不能用语言描述我是多么高兴,你为我节省了这么多时间! (2认同)

And*_*aus 97

如何在Angular 1.x中简单地返回预先解析的promise

已解决的承诺:

return $q.when( someValue );    // angular 1.2+
return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6
Run Code Online (Sandbox Code Playgroud)

拒绝的承诺:

return $q.reject( someValue );
Run Code Online (Sandbox Code Playgroud)

  • 我认为应该选择这个答案. (2认同)

cha*_*tfl 6

如果我想在数组或对象中实际缓存数据,我通常会这样做

app.factory('DataService', function($q, $http) {
  var cache = {};
  var service= {       
    getData: function(id, callback) {
      var deffered = $q.defer();
      if (cache[id]) {         
        deffered.resolve(cache[id])
      } else {            
        $http.get('data.json').then(function(res) {
          cache[id] = res.data;              
          deffered.resolve(cache[id])
        })
      }
      return deffered.promise.then(callback)
    }
  }

  return service

})
Run Code Online (Sandbox Code Playgroud)

DEMO