Я пытаюсь автоматизировать процесс обновления некоторых данных в серверной части моей программы. Я использую свой интерфейс Angular, где я создал функцию, доступ к которой имеет только главный пользователь, и это должно заставить его входить в систему в каждой администрации (арендаторе), где он будет загружать некоторые объекты с некоторыми неправильными данными внутри, запрашивая у службы Google правильные данные и обновите данные в бэкэнде, а также выполните все эти операции для каждого клиента.
Я задумал написать каждую из этих операций как наблюдаемую и использовать concat, чтобы делать все по порядку, но прежде чем даже закончить получение правильных данных, что я делаю внутри крана, он уже пытается войти в систему в следующем арендаторе, поэтому, когда он на самом деле имеет правильные данные, он не сможет загрузить их в серверную часть, поскольку он откажется от них как от неправильного клиента.
Я думаю, что эта проблема вызвана длительными операциями с краном (и мне нужно сделать кое-что, что потребует еще больше времени).
Это мой фрагмент кода (без посторонних вещей):
const obsList = [] as Observable<any>[];
this.assignedTenants.forEach(tenant => {
const obsList2 = [] as Observable<any>[];
obsList.push(this.authenticationService.login(new Credentials(usr, psw), tenant.id));
obsList.push(this.structureService.getStructuresWithWrongAltitude()
.pipe(tap(structuresReceived => {
obsList2 = [] as Observable<any>[];
if (structuresReceived != null && structuresReceived.length > 0) {
structuresReceived.forEach(s => {
this.getElevation(new google.maps.LatLng(s.centro.coordinates[0], s.centro.coordinates[1]))
.then(a => {
s.centroAltitudine = a;
this.obsList2.push(this.structureService.putStructure(s));
})
.catch();
});
}
})));
obsList.push(forkJoin(obsList2)
.pipe(tap(() => this.storageService.logout())));
});
concat(...obsList).subscribe();
Как вы можете видеть, этот код должен создать и выполнить 3 наблюдаемых объекта для каждого клиента: первый используется для входа в систему, второй - для получения неправильных данных, получения правильных данных и подготовки к третьему, который обновит данные. Как я уже сказал, обычно при входе в кран из второго наблюдаемого, getStructuresWithWrongAltitude, я уже могу видеть, используя журналы, что он пытается войти в систему для других клиентов.
Моя теория состоит в том, что как только он получает неправильные данные, он пытается выполнить третью наблюдаемую, которая все еще недействительна, и перейти к следующему клиенту, но я не знаю, как это исправить.
Мне понадобится способ, чтобы вторая наблюдаемая не испускалась, пока нажатие не будет завершено, или другой способ предотвратить продолжение concat до завершения других операций
Спасибо за помощь
РЕДАКТИРОВАТЬ:
Я смог исправить это, превратив getElevation (который возвращает обещание) в наблюдаемый список, который, в свою очередь, создаст новый наблюдаемый список для сохранения данных.
Как я уже сказал, мне нужно сделать что-то очень похожее, с той разницей, что на этот раз крану действительно придется выполнять много вычислений, которые займут много времени, поэтому я не смогу использовать то же исправление, что и мой Остается вопрос: можно ли заставить concat ждать, пока кран не закончится?
РЕДАКТИРОВАТЬ 2 для пояснения
Как я сказал в своем последнем редактировании, этот конкретный пример был решен путем преобразования материала внутри крана в другие наблюдаемые, но у меня почти такая же проблема с другой функцией.
этой функции необходимо найти файлы внутри папки перед их загрузкой
const folderInput = this.folderInput.nativeElement;
folderInput.onchange = () => {
this.filesUploaded = folderInput.files;
const obsList = [] as any[];
this.assignedTenants.forEach(tenant => {
const obsList2 = [] as Observable<any>[];
obsList.push(this.authenticationService.login(new Credentials(usr, psw), tenant.id));
obsList.push(this.fileService.getAll()
.pipe(
tap(filesReceived => {
if (filesReceived != null && filesReceived.length > 0) {
console.log('upload picture: received list of files to update');
let i = filesReceived?.length;
filesReceived?.forEach(f => {
const pathReceived = (f.originalFilename as string).substr(1).split('\\');
let found = false;
let index = -1;
// searching the file in the folder
//...
if (found) {
console.log('found a file');
const selectedFile = this.filesUploaded[index];
const formData = new FormData();
formData.append('file', selectedFile, selectedFile.name);
obsList2.push(this.fileService.updateFile(formData, f.id));
}
i--;
});
console.log('upload picture: updated obsList2');
obsList.push(forkJoin(obsList2).subscribe(() => {
console.log('upload picture: uploaded pictures');
this.storageService.logout();
}));
}
}))
);
});
this.loadingIndicatorService.loading$.next(true);
let counter = obsList.length;
concat(...obsList).subscribe(() => {
counter--;
console.log('upload pictures: remaining phases: ' + counter);
if (counter <= 0) {
this.loadingIndicatorService.loading$.next(false);
}
});
};
folderInput.click();
obsList2
. Вы объявляете его в третьей строке, но затем сбрасываете в седьмой строке с помощью кодаobsList2 = [] as Observable<any>[];
. Вы уверены, что это действительно работает в Typescript? Как только мы это проясним, мы можем приступить к остальному. - person Picci   schedule 11.02.2021