AngularJS deferred.reject 不工作但 $q.reject 工作

AngularJS deferred.reject not working but $q.reject working

我对 Angular JS deferred 和 $q 感到困惑。我发现这个 SO Question 解释了 $q.defer()$q 之间的区别。它解释了

$q.reject is a shortcut to create a deferred and then reject it immediately

所以 $q.reject() 必须等于

var deferred = $q.defer(); deferred.reject(),如果不是请说明两者的实际区别

但就我而言,$q.reject() 有效,但 deffered.reject() 无效。我们还需要 return 拒绝像 $q.reject() 但不是 deferred.reject() 的承诺。我见过 deffered.reject()

上没有 return 的示例

这是代码

 var deferred = $q.defer();
 myService.getData()
 .then(function(response){
   deferred.notify('Just a notification');
   deferred.reject('rejected');
 })
 .then(function(response) {
   console.log('done');      
 }, function(response) {
   console.log('rejected');
 })

这行不通,但是当我用 $q.reject() 替换 deferred.reject 时,promise 已被拒绝,控制权移至后面的 then 块的错误函数。

非常感谢任何帮助。提前致谢。

确保您返回的是承诺。

function getData() {
    var deferred = $q.defer();
    myService.getData()
        .then(function (response) {
           deferred.resolve('Just received a notification');
        }).catch(function (err) {
           deferred.reject(err); 
        };

    return deferred.promise;
}

getData().then(function (response) {
    console.log('done');
}, function (response) {
    console.log('rejected');
});

当您使用 deferred.reject 时它不起作用,因为您没有 return 新的拒绝承诺。你可以同时使用 $q.reject()deferred.reject() 你只需要在这两种情况下 return 一个承诺。

你需要明白

  • $q.reject()被拒绝的promise对象
  • deferred.reject() 不是 承诺,而是延迟对象,它在其属性之一(即 $promise)中拒绝了承诺。

所以你可以 return 任何对象或值,它将成为一个新的承诺对象,并将传递到链中的下一个 then 块。但是,当您 return deferred.reject() 时,它将作为某个对象传递(再一次,它不是一个承诺,但它在 内部 中有一个承诺),下一个承诺将得到当然成功解决了。

如果您 return 相应的承诺,它将与 deferred 一起正常工作:

var deferred = $q.defer();
myService.getData()
    .then(function(response) {
        deferred.notify('Just a notification');
        deferred.reject('rejected');
        return deferred.promise;
        //return $q.reject();
    })
    .then(function(response) {
        console.log('done');
    }, function(response) {
        console.log('rejected');
    });

最后回答你的问题:$q.reject() 是状态为 "rejected" 的承诺对象。 deferred.reject() 不是 承诺,但它已拒绝内部承诺对象作为 deferred.$promise。用什么?您应该使用 $q.reject(),在这种情况下使用虚拟延迟对象是多余的并且被认为是不好的做法,事实上它甚至有一个名称 deferred anti-pattern.

这是与 Q (https://github.com/kriskowal/q)

var def = Q.defer();
def.promise
.then(
    function(ok){
        return ok;
    },
    function(err){
        var d = Q.defer();
        d.reject(err);
        return d.promise;
    }
)
.then(
    function(ok){
        console.log('ok',ok);
    },
    function(err){
        console.log('err',err);
    }
);
def.reject('error');