AngularJS承诺通知不工作

jcm*_*jcm 14 promise angularjs

我有以下控制器代码:

 .controller('Controller1', function ($scope, MyService) {

    var promise = MyService.getData();
    promise.then(function(success) {
        console.log("success");
    }, function(error) {
        console.log("error");
    }, function(update) {
        console.log("got an update!");
    }) ;
Run Code Online (Sandbox Code Playgroud)

}

在我的services.js中:

 .factory('MyService', function ($resource, API_END_POINT, localStorageService, $q) {
   return {
       getData: function() {
           var resource = $resource(API_END_POINT + '/data', {
               query: { method: 'GET', isArray: true }
           });

           var deferred = $q.defer();
           var response = localStorageService.get("data");
           console.log("from local storage: "+JSON.stringify(response));
           deferred.notify(response);

           resource.query(function (success) {
               console.log("success querying RESTful resource")
               localStorageService.add("data", success);
               deferred.resolve(success);
           }, function(error) {
               console.log("error occurred");
               deferred.reject(response);
           });

           return deferred.promise;
       }
   }

})
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,deferred.notify呼叫似乎永远不会执行并在控制器内被接收.我这里有什么不对吗?我不知道如何让通知执行.

小智 21

我设法通过在$ timeout函数中包装notify来使它工作:

$timeout(function() {
  deferred.notify('In progress')}
, 0)
Run Code Online (Sandbox Code Playgroud)

看起来你不能在返回promise对象之前调用notify,这有点意义.

  • @PixMach:回调永远不会立即被调用,您可以在这里测试它以查看哪个首先触发:http://jsfiddle.net/yL63vwpL/2/。(Angular 的 $timeout 只是一个奇特的 setTimeout)。在计时器上输入 0 将会被浏览器纠正为最小值。在 HTML4 中,最小值为 10 毫秒,在 HTML5 中为 4 毫秒。此外,您输入的时间从来都不是准确的,只是一个近似值 - 浏览器会尝试尽可能接近该值。您还可以调用不带延迟参数的 $timeout( function1 ) 来获取最小值。 (2认同)

Flo*_*ian 1

我试图在这里重现你的问题。看来,您不能notify直接调用承诺,而必须包装到$apply调用中。

$q 另请参阅此处的文档。

引用示例中的确切行:

由于此 fn 在事件循环的未来回合中执行异步,因此我们需要将代码包装到 $apply 调用中,以便正确观察模型更改。

您可以自己尝试一下并稍微更改一下代码:

deferred.notify(response); // should not work

resource.query(function (success) {
    deferred.notify('Returning from resource'); // should work
    console.log("success querying RESTful resource")
    localStorageService.add("data", success);
    deferred.resolve(success);
}, function(error) {
    deferred.notify('caught error!'); //should also work
    console.log("error occurred");
    deferred.reject(response);
});
Run Code Online (Sandbox Code Playgroud)