Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
399 views
in Technique[技术] by (71.8m points)

javascript - 如何在Angular 8中触发动态创建的HTTP请求列表?(How can I fire off a dynamically created list of http requests in Angular 8?)

In a previous AngularJS app that I am migrating to Angular 8, I had a function that would download functions by binding them and placing them in an array, waiting to be called using a reduce function.(在我要迁移到Angular 8的以前的AngularJS应用程序中,我有一个函数可以通过将函数绑定并放置在数组中来下载函数,等待使用reduce函数调用。)

For example:(例如:) function stageForDownload() { $scope.files.forEach(function (file) { if (file.checked) { $scope.downloadFunctions.push(downloadFile.bind(null, file)); } }); } function downloadStaged() { $scope.downloadFunctions.reduce( function (prev, next) { return prev.then(next); }, Promise.resolve()) .then( /* do something now that all files are downloaded */ ); } } This code would essentially resolve promises in a one by one fashion until the list of functions were empty.(此代码本质上将以一种一种方式解决承诺,直到函数列表为空。) As in Angular 8, the structure of promises works in a different way (meaning they use the ECMA 6 implementation now) and I am unsure of how to migrate this code.(与Angular 8中一样,promise的结构以不同的方式工作(这意味着它们现在使用ECMA 6实现),我不确定如何迁移此代码。) Furthering my confusion, the HttpClient angular provides now returns an Observable which can be subscribed to;(更令人困惑的是,HttpClient所提供的角度现在返回了一个可以订阅的Observable;) and while rsjx's forkJoin() method seems to support exactly what I want to do, it will not accept a list of bound functions.(尽管rsjx的forkJoin()方法似乎完全支持我想做的事情,但它不会接受绑定函数的列表。) I simply just need to know when all of the functions are completed, as they are voids that run an export service method to download a file.(我只需要知道所有功能何时完成,因为它们是运行导出服务方法下载文件的空白。) So I do not necessarily need to return / subscribe to any data from these methods that are being reduced.(因此,我不一定需要从减少的这些方法中返回/订阅任何数据。) Edit:(编辑:) There are two more functions involved that I forgot to mention.(我忘了提到另外两个功能。) Here is downloadFile, which is responsible for calling the exportService.(这是downloadFile,它负责调用exportService。) function downloadFile(file) { var deferred = $q.defer(); $scope.date = formatDate($scope.datepicker.selectedDate); $scope.fileDate = dateToYMD($scope.datepicker.selectedDate); exportService.exportData(file.FileNamePrefix + " " + $scope.fileDate + ".xlsx", 'SOME_API_LOCATION' + $scope.date, file).then( function () { deferred.resolve(); }, function (error) { deferred.reject(); notificationService.displayError("Internal Error!"); }); return deferred.promise; } And here is the exportService itself:(这是exportService本身:) (function (app) { 'uuse strict'; app.factory('exportService', exportService); exportService.$inject = ['$q', '$http']; function exportService($q, $http) { var service = { exportData: exportData, createFilename: createFilename }; function exportData(filename, url, data) { var config = { responseType: 'arraybuffer' }; return $http.post(url, data, config).then( function (response) { var deferred = $q.defer(); var data = response.data; var status = response.status; var headers = response.headers(); var octetStreamMime = 'application/octet-stream'; var success = false; var contentType = headers['content-type'] || octetStreamMime; try { // Try using msSaveBlob if supported var blob = new Blob([data], { type: contentType }); if (navigator.msSaveBlob) navigator.msSaveBlob(blob, filename); else { // Try using other saveBlob implementations, if available var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob; if (saveBlob === undefined) throw "Not supported"; saveBlob(blob, filename); } success = true; deferred.resolve(); } catch (ex) { } if (!success) { // Get the blob url creator var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL; if (urlCreator) { // Try to use a download link var link = document.createElement('a'); if ('download' in link) { // Try to simulate a click try { // Prepare a blob URL var blob = new Blob([data], { type: contentType }); var url = urlCreator.createObjectURL(blob); link.setAttribute('href', url); // Set the download attribute (Supported in Chrome 14+ / Firefox 20+) link.setAttribute("download", filename); // Simulate clicking the download link var event = document.createEvent('MouseEvents'); event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null); link.dispatchEvent(event); success = true; deferred.resolve(); } catch (ex) { } } if (!success) { // Fallback to window.location method try { var blob = new Blob([data], { type: octetStreamMime }); var url = urlCreator.createObjectURL(blob); window.location = url; success = true; deferred.resolve(); } catch (ex) { deferred.reject(); } } } } return deferred.promise; }, function (error) { return $q.reject(error); }); } } })(angular.module('app')); So it appears my problem is not necessarily firing off a dynamically created list of http requests, but rather how to convert promises using $q into ECMA6+ promises.(因此,看来我的问题不一定是启动动态创建的HTTP请求列表, 而是如何使用$ q将诺言转换为ECMA6 +诺言。)   ask by Tyler Lyle translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use from to turn Promise into Observable .(您可以使用fromPromise变成Observable 。)

const observables: Observable<any>[] = promises.map(promise => from(promise)); After that, you can unleash RxJS.(之后,您可以释放RxJS。) You can use forkJoin to get an Observable of all your promises:(您可以使用forkJoin获得所有诺言的Observable :) forkJoin(observables).subscribe(files => { // do things with files }); The way forkJoin is implemented it will only fire once the observables complete .(实现forkJoin的方式只有在可观察对象完成后才会触发。) It will not be an issue here, but if you want to batch requests that do not complete, consider zip .(在这里这不是问题,但是如果您要批量处理未完成的请求,请考虑使用zip 。) If you want to do use HttpClient , you would just have a different source of your observables.(如果您想使用HttpClient ,您将只有一个不同的可观察源。) const observables: Observable<any>[] = urls.map(url => this.httpClient.get(url)); but the forkJoin would be the same.(但forkJoin相同。) The key is that forkJoin accepts an array of Observables .(关键是forkJoin接受一个Observables数组。)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...