gpt4 book ai didi

web-services - 如何使用 AngularJS 进行顺序 Rest Web 服务调用?

转载 作者:行者123 更新时间:2023-12-04 05:16:01 26 4
gpt4 key购买 nike

我想知道如何使用 AngularJS 进行顺序 Web 服务调用?
为简化起见,当我们得到第一个 web 服务的结果时,我们称之为第二个。
我已经找到了解决方案,但我真的不喜欢它。我认为必须有更好的解决方案,这就是我发布问题的原因。
这是我的代码(并且有效)。

var uploadFile = function(file) {
szUrl = globalServ.datas.szUrl+"transactions/"+globalServ.transactionId+"/file";
var postData = {};
postData['name'] = "MyFile"+file;
postData['file'] = $scope.wsFiles[file];
$http({
method: 'POST',
url:szUrl,
headers: {'Content-Type': false, 'Authorization': globalServ.make_base_auth()},
transformRequest: formDataObject,
data:postData,
}).success(function(response) {
$scope.qFiles[file].resolve(file);//This will allow to call "then" method
}).error(function (data, status, headers, config) {
$scope.errorMsg = globalServ.getErrorMsg(status, data);
$scope.filesAdded = false;
});
}
$scope.uploadFiles = function() {
delete $scope.errorStatus;

$scope.qFiles = [];
$scope.uploadOver = false;

for(file in $scope.wsFiles) {
var q1 = $q.defer();
q1.promise.then(function(curFile) {
if(curFile < $scope.wsFiles.length - 1) {
uploadFile(curFile+1);
} else {
$scope.uploadOver = true;//We uploaded all contracts so now can stop to show loading button
}
});
$scope.qFiles.push(q1);
}
uploadFile(0);//We start to upload contracts
};

欢迎所有批评者。先感谢您。

最佳答案

首先接受这一点,如果你要使用 Promise,你想在任何地方使用它们。它们已经提供了您尝试手动创建的许多结构。此外,尽量避免向 $scope 添加内容。 (或任何其他全局)除非绝对必要。构建所有实用程序函数,使它们独立于范围和任何 View 更新等。

上传文件

接下来要做的是制作uploadFile回一个 promise 。我们还希望它不使用 $scope 而是将它需要的所有信息作为参数。因此,我提出以下建议:

function uploadFile(file) {
szUrl = globalServ.datas.szUrl+"transactions/"+globalServ.transactionId+"/file";
var postData = {};
postData['name'] = "MyFile"+file.name;
postData['file'] = file.data;
return $http({ // <--------------------------- return the promise here
method: 'POST',
url:szUrl,
headers: {'Content-Type': false, 'Authorization': globalServ.make_base_auth()},
transformRequest: formDataObject,
data:postData,
}).then(function onSuccess(response) { //<--- `.then` transforms the promise here
return file
}, function onError(response) {
throw globalServ.getErrorMsg(response.status, response.data);
});
}

其中 file 是形式 {name: 'file name', data: 'contents of file post'} 的对象

上传文件

对于上传文件,我们必须决定是并行上传还是顺序上传。并行通常会更快,但会使用更多资源(内存、带宽等)。如果您需要同时做很多其他事情,您可能希望连续执行它们。您可能还想选择第三个选项(此处未涵盖),例如一次最多 5 个并行上传。

无论哪种方式,我们都将创建一个函数,该函数采用 file 的数组。对象并上传它们,然后返回一个 promise ,该 promise 在操作完成时被解析,如果失败则被拒绝。

平行线

要并行执行,我们只需上传每个文件,然后使用 $q.all等待所有上传完成。
function uploadFilesParallel(files) {
var uploads = []
for(var i = 0; i < files.length; i++) {
uploads.push(uploadFile(files[i]))
}
return $q.all(uploads)
}

顺序的

按顺序上传只是稍微复杂一点。原则上我们需要做的是让每个操作在开始之前等待前一个操作完成。为此,我们首先创建一个由已解决的 promise 表示的虚拟初始操作。然后我们通过循环跟踪上一个操作,以便我们可以在上传之前始终等待上一个操作。
function uploadFilesSequential(files) {
var previous = $q.when(null) //initial start promise that's already resolved
for(var i = 0; i < files.length; i++) {
(function (i) {
previous = previous.then(function () { //wait for previous operation
return uploadFile(files[i])
})
}(i)) //create a fresh scope for i as the `then` handler is asynchronous
}
return previous
}

用法

最后是附加到范围的原始 uploadFiles 操作。此时,您可以执行所有必要的操作来更新您的 View 。请注意,到目前为止我还没有触及任何全局变量。这样做的原因是为了确保多次调用 uploadFilesSequentialuploadFilesParallel不会发生冲突并导致问题。

我没有对以下功能做出同样的保证。如果并行调用它多次,多次操作可能会导致奇怪的行为。
$scope.uploadFiles = function (parallel) {
delete $scope.errorStatus;
$scope.uploadOver = false;

var files = [];

for(file in $scope.wsFiles) {
files.push({
name: file,
data: $scope.wsFiles[file]
})
}

var uploadOperation
if (parallel) {
uploadOperation = uploadFilesParallel(files)
} else {
uploadOperation = uploadFilesSequential(files)
}
uploadOperation
.then(function(file) {
$scope.uploadOver = true;
}, function (err) {
$scope.errorMsg = err;
$scope.filesAdded = false;
});
};

显然,如果您总是使用并行或总是使用顺序上传,那么您可以稍微简化一下。请注意,这样做是多么简单,我们所要做的就是处理 View 逻辑和 uploadFilesSequential 的实际实现。或 uploadFilesParallel完全隐藏在我们面前。正是这种封装对于使大型系统编程成为可能至关重要。

future

JavaScript 的 future 版本(EcmaScript 6)即将推出,这将使顺序版本更容易。您将能够大致像这样重写它:
var uploadFilesSequential = Q.async(function* (files) {
for(var i = 0; i < files.length; i++) {
yield uploadFile(files[i])
}
})

哪里 yield是一个特殊的关键字,等待 promise 被解决。不幸的是,这可能还需要几年的时间,您才能在现实世界的代码中使用并在浏览器中运行。

关于web-services - 如何使用 AngularJS 进行顺序 Rest Web 服务调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16854963/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com