【问题标题】:$q.all is resolving before the returns$q.all 在返回之前解决
【发布时间】:2013-12-29 14:25:38
【问题描述】:

$q.all 在其任一函数解析之前解析。

我正在使用 $.ajax 将两个文件上传到 azure blob 存储(我无法让 $http 工作):

 function doPhotos (result, i)
    {
        var d = $q.defer();
        var requestData = new Uint8Array($scope.files[i].postArray);
        $.ajax({
            url: result.photos[i].imageUri,
            type: "PUT",
            data: requestData,
            processData: false,
            beforeSend: function (xhr)
            {
                xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
                xhr.setRequestHeader('x-ms-blob-content-type', $scope.files[i].type);
                xhr.setRequestHeader('x-ms-meta-uploadvia', 'CORS Demo');
                xhr.setRequestHeader('Content-Length', requestData.length);
            },
            success: function (data, status)
            {
                d.resolve(data);

            },
            error: function (xhr, desc, err)
            {
                console.log('error uploading photo ' + desc);
                d.resolve(err);


            }
        });
        return d.promise;

    }

这是设置$q.all 并在ng-click 上调用的函数:

$scope.createVotation = function () {
        services.photoset.create($scope.model).then(function (result) {
            $scope.model.id = result.id;
            var doPhotosArray= [];
            for (var i in result.photos) {
                doPhotosArray[i] = doPhotos(result, i);    
            }

            $q.all(doPhotosArray).then(function (data)
            {
                // this is being called almost immediately before the photos upload
                $scope.safeApply(function ()
                {
                    $scope.submitting = false;
                    $location.path('/vote/update/' + $scope.model.id);

                });
            });

        });
    }
};

html:

<button ng-click='createVotation()'>Create</button>

q.all-&gt;then 甚至在第一个 doPhoto 解析被调用之前就被调用了。我不确定使用 jQuery 的 ajax 是否存在问题,但我的理解是 $q.all 应该等到两个承诺(在我的情况下有 2 个)都得到满足后再输入它的 then

作为一个额外的转折点,照片正在上传,这样就可以正常工作了,$q.all 没有等待。

【问题讨论】:

  • 应该可以正常工作。请参阅此演示,该演示将延迟增加 1/2 秒以解决 4 个请求。 plnkr.co/edit/Zawd6dBZh6FlRPD0gsrV?p=preview
  • 查看这个插件:plnkr.co/edit/XpGMfak4hzTKic8R3wdR?p=preview q.all 永远不会解决,尽管两个函数都可以。虽然与我原来的问题不同,但不确定它为什么会这样。我尝试了有无超时来模拟几秒钟。
  • 很奇怪……和我的演示几乎一样的概念……不明白为什么它不会触发
  • 我在我的程序中将 $.ajax 换成了 $http,它的行为是一样的。 q.all 立即被调用。我在 ajax/http 的成功/解析函数中设置了一个断点,它在 q.all 运行后一分钟被调用(上传一个 1.5 mb 的文件)。
  • 已经玩了一段时间了....我无法解释为什么,但是如果我不使用 ng-clcik 并在 jQuery 点击处理程序中的 $q.all() 之后调用 $apply()它可以工作plnkr.co/edit/mtGo2aAhqthNGEP7Wjjo?p=preview。似乎与ng-click 导致摘要循环有关。可能会尝试将此移动到服务中

标签: jquery angularjs promise


【解决方案1】:

在做了一些研究并考虑了来自@charlietfl 的各种 cmets 之后,我可以让 $q.all 正常工作的唯一方法是将函数调用分配给一个变量,然后将其推送到正在生成的数组中传递给 q.all。

for (var i in result.photos)
{
    var output = doPhotos(result, i);
    doPhotosArray.push(output);
} 

我用作参考的各种示例似乎表明我最初问题中的代码应该可以工作,但不能。

【讨论】:

  • 我知道这是在 2013 年,但问题是:ajax call -&gt; return promise at some point -&gt; q.all,所以当你调用q.all 时,promise 甚至可能不会退出,我认为q.all 不会等待,这可以造成问题。理想情况下,您只想将现有的 Promise 作为 obj.p1、obj.p2 或数组 [p1, p2] 传递给q.all。 Q all 将等待 p1, p2 ...而不是之前发生的其他 ajax 内容。
猜你喜欢
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
相关资源
最近更新 更多