Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angularjs$http使用$q.defer返回未完成的结果_Javascript_Angularjs_Angular Promise_Angular Http - Fatal编程技术网

Javascript Angularjs$http使用$q.defer返回未完成的结果

Javascript Angularjs$http使用$q.defer返回未完成的结果,javascript,angularjs,angular-promise,angular-http,Javascript,Angularjs,Angular Promise,Angular Http,我对angular有一个问题,即结果在实际完成之前返回到我的控制器,即使我正在使用$q.defer功能。我在我的服务中有以下功能 getFileInfo : function (fulfillmentId) { var pdfResults = []; var jpgResults = []; var orderDetails = {}; var deferred = $q

我对angular有一个问题,即结果在实际完成之前返回到我的控制器,即使我正在使用$q.defer功能。我在我的服务中有以下功能

      getFileInfo : function (fulfillmentId)
        {
            var pdfResults = [];
            var jpgResults = [];
            var orderDetails = {};
            var deferred = $q.defer();


            $http.get(appConstants.api_url + '/references/' + fulfillmentId + '/files?max=2000')
                . then (function (fileResults)
                {
                    angular.forEach(fileResults.data.entities,function(value)
                    {
                        if(value.file.extension == 'pdf')
                        {
                            pdfResults.push({files : value});

                        }

                        if(value.file.extension == 'jpg')
                        {
                            jpgResults.push({files : value});
                        }
                    });

                    orderDetails.jpgResults = jpgResults;

                    return pdfResults;

                })
                .then (function (pdfResults)
                {
                    angular.forEach(pdfResults,function(value,key)
                    {

                        var fileUuid = value.files.file.file_uuid;

                        return $http.get(appConstants.api_url + '/resources/' + fileUuid + '/tags')
                            .then (function (preflightResults)
                        {

                            var deserializeJson = [];
                            deserializeJson.push(angular.fromJson(preflightResults.data.entities[0].resource_json));
                            var formatedPreflightResults = localAPI.addUIMessages(deserializeJson);

                            pdfResults[key].preflightResults = formatedPreflightResults;
                        });

                    });

                    orderDetails.pdfResults = pdfResults;

                    deferred.resolve(orderDetails);
                });


            return deferred.promise;


        }
我从我的控制器上这样叫它:

 conformAPI.getFileInfo($scope.fulfillmentId)
        .then (function (results)
        {
            console.log(results);
            console.log(results.pdfResults[0]);
            console.log(results.pdfResults[0].preflightResults)

        });

我遇到的问题是,我做的最后一个控制台日志是未定义的。其他一切结果都很好。第一个和第二个控制台都有preflightResults对象,但它的添加似乎有点晚。我认为使用$q.delay在所有事情完成之前不会返回任何内容。关于如何解决这个问题有什么想法吗?

看起来您没有在等待“getFile”get请求的结果。 我重构了你的代码。因为我不能运行它,所以它可能不起作用,但你应该明白我的意思

getFileInfo: function (fulfillmentId) {

var pdfResults = [];
var jpgResults = [];
var orderDetails = {};
var deferred = $q.defer();

function getByFileId(fileUuid, preflightResults) {

    return $http.get(appConstants.api_url + '/resources/' + fileUuid + '/tags')
        .then(function (preflightResults) {
        var deserializeJson = [];
        deserializeJson.push(angular.fromJson(preflightResults.data.entities[0].resource_json));
        var formatedPreflightResults = localAPI.addUIMessages(deserializeJson);

        return formatedPreflightResults;
    });
}

function getFiles(pdfResults) {

    var subDefer = $q.defer();
    var current = 0;

    angular.forEach(pdfResults, function (value, key) {
        current += 1;
        var fileUuid = value.files.file.file_uuid;

        getByFileUuid(fileUuid, preflightResults)
            .then(function (results) {

            pdfResults[key].preflightResults = results;

            // need to know when done with all
            if (pdfResults.length === current) {
                subDefer.resolve(pdfResults);
            }
        });
    });

    return subDefer.promise;
}

$http.get(appConstants.api_url + '/references/' + fulfillmentId + '/files?max=2000')
.then(function (fileResults) {

    angular.forEach(fileResults.data.entities, function (value) {

        if (value.file.extension == 'pdf') {
            pdfResults.push({ files: value });
        }

        if (value.file.extension == 'jpg') {
            jpgResults.push({ files: value });
        }
    });

    orderDetails.jpgResults = jpgResults;
    return pdfResults;

}).then(getFiles).then(function(pdfResults) {

    orderDetails.pdfResults = pdfResults;
    deferred.resolve(orderDetails);
});

return deferred.promise;

}

您过早地兑现了承诺

由于第一个then()只返回一个对象,因此第二个then()将立即返回。这就是代码所做的(粗略的伪代码):

$http.get().then(首先返回$http.get)

一旦启动第一个文件的get,就返回(
return$http.get(appConstants.api_url+
)。此时,只有顶部的第一个$http.get肯定已解析。您可能会看到(第一个文件的)第二个$http.get很快解决,但您还没有启动更多文件的$http.get

如果删除中间的返回以便生成所有$http.get,那么您在这段代码中可能的目标是:

$http.get()。然后(启动所有$http.get并解析承诺)

一旦您遍历了所有文件并使用$http.get启动它们,您就可以解决承诺。这也有同样的问题——承诺解决得太早。所有的get都已发送出去,但您不能确定它们是否已返回

你可以做的是:

$http.get().then(启动所有$http.get并在它们全部完成后解析承诺)

例如,您可以将它们映射到$http.get:filePromises=pdfResults.map(函数(e)$http.get(e))的数组,而不是pdfResults上的forEach


然后您将
返回$q.all(filepromissions)
在您现在已延迟的末尾。解析(orderDetails)。

实际上,根据数据的输入方式,我的方法是正确的。啊,因此该值有一个属性“files”…?啊,现在我看到了。您正在分配pdfResults[key].Preflight导致回调。让我给你一个更好的答案。是的,文件是一个属性。这里有一个关于链接承诺的精彩视频: