【发布时间】:2019-05-19 23:38:33
【问题描述】:
我正在使用 TypeScript 将 AngularJS 应用程序转换为 Angular 7。
我在将一些复杂的嵌套 Promise 转换为 Observables 时遇到了一些问题。
这是我正在处理的代码示例:
signup.component.js
function SomethingSignupController(somethingApplication) {
function activate() {
getApplication();
}
function getApplication() {
vm.getFromServer = false;
vm.promises = [];
SomethingRepo.get().then(function(application) {
vm.getFromServer = true;
vm.application = application;
vm.promises.push(Something.getCompany().then(function(company) {
vm.company = company;
if (vm.company.structure === ‘more_25’) {
return SomethingRepo.getAllOwners().then(function(owners) {
vm.owners = owners;
for(var i = 0; i < vm.owners.length; i++) {
vm.promises.push(getOwnerFiles(vm.owners[i]));
}
}
}
}
vm.promises.push(SomethingRepo.getSomethingOne().then(function(somethingOne) {
vm.somethingOne = somethingOne;
}
vm.promises.push(SomethingRepo.getSomethingTwo().then(function(somethingTwo) {
vm.somethingTwo = somethingTwo;
}
vm.promises.push(SomethingRepo.getSomethingThree().then(function(somethingThree) {
vm.somethingThree = somethingThree;
}
/* and a few more like the above */
$q.all(vm.promises).then(function(){
postGet();
}).finally(function() {
vm.promises = [];
});
}
}
function postGet() {
/* does something with the data acquired from SomethingRepo */
}
/* when an application is send */
function send() {
somethingApplication.promises = [];
somethingApplication.errors = [];
if (vm.getFromServer) {
update();
} else {
create();
}
}
function update() {
somethingApplication.promises.push(SomethingRepo.update(vm.application).then(angular.noop, function(error) {
somethingApplication.parseErrors(error, ‘Some error’);
}));
patchInfo();
}
function create() {
}
function patchInfo() {
somethingApplication.promises.push(SomethingRepo.patchAccount(vm.account).then(angular.noop, function(error) {
somethingApplication.parseErrors(error, ‘Account error: ‘);
}
/* a few more patches */
$q.all(somethingApplication.promises).then(function() {
/* display dialog */
}, angular.noop).finally(function() {
postGet();
somethingApplication.promises = [];
if (somethingApplication.errors.length >= 1) {
vm.errors = somethingApplication.errors;
}
});
}
}
somethingApplication.service.js
function somethingApplication(SomethingRepo) {
var promises = [], errors = [];
var service = {
promises: promises;
errors = errors;
parseErrors: parseErrors;
};
return service;
function parseErrors(error, base_string) {
angular.forEach(error.data.erros, function(value_params, key_params) {
this.errors.push(base_string + ‘ ‘ + key_params.replace(/_/g, ‘ ‘) + ‘ ‘ + value_params);
}, this);
}
}
somethingRepo.js
function SomethingRepo(Server) {
function get() {
return Server.get(‘/something/application’, null, {noGlobal: true});
}
}
我已经减少了文件,但它们包含更多这样的代码。 控制器的目的是为另一个网站创建或更新应用程序。在我的网站上,我有一个与另一个网站上的表单相对应的字段表单。如果您已经提交了申请,但想要更新它,您已经提交的信息将从其他网站加载。
问题是,为了创建或更新应用程序,许多不同的端点请求发布到。
在 AngularJS 中,我存储来自每个请求的 Promise,并在最后异步运行它们。在 TypeScript 和 Angular 中,我想使用 Observables 并订阅数据更改。
我该如何开始?如何从另一个 Observable 订阅 Observable 所需的参数?任何建议如何进行?
【问题讨论】:
-
Observable支持ToPromise方法,将 Observable 转换为可调用的 Promise。如果您想保留Promise.all方法,您可以。否则,您可以考虑使用 RxJs 建议的其他方法,例如.concatMap、forkJoin等。尽可能利用async await,这将帮助您跟踪它在迁移阶段所做的工作。 -
“我如何开始?如何订阅另一个 Observable 的所需参数?任何建议如何继续?”如果我理解正确,您正在寻找
forkJoin。您可以将其与from(promise)结合使用以创建一个可观察的对象,该可观察对象等待一组承诺解决,然后发出已解决值的列表。 -
我不想保留
Promise方法。你有一个具体的例子来说明我如何forkJoin我的特定代码吗?不是我想让你做这项工作,但我很难将我读到的关于forkJoin的内容应用到我的代码中 -
这可能会有所帮助 - stackoverflow.com/questions/39319279/…
-
@FrankfromDenmark forkJoin 与 Promise.all 完全一样:您提供 Observables 的数组(或列表)(angular 的 HttpClient.get 返回一个
Observable默认情况下),它的回调会触发所有解析的值。 FK82 提供了上面的官方文档。看看示例 5,它非常接近您的用例。
标签: javascript angular typescript promise