#angular #rxjs
#angular #rxjs
Вопрос:
У меня возникли некоторые проблемы с упорядочением двух наблюдаемых объектов, чтобы первый выполнялся перед вторым. Я начал пытаться использовать concatMap
без какой-либо удачи … возможно, это не лучший вариант, но, основываясь на описаниях операторов отображения более высокого порядка, я подумал, что это лучший.
Первый наблюдаемый объект, который необходимо запустить, очень прост:
this.workflowService.getFolderActions().subscribe(tasks => {
this.tasks = tasks;
});
Для правильной работы второго наблюдаемого объекта требуется свойство tasks
(или this.tasks
). Второй наблюдаемый объект:
this.route.data
.pipe(
switchMap(x => {
return this.route.paramMap;
}))
.subscribe(params => {
this.paymentId = params.get('id');
this.task = this.workflowService.getTask(this.paymentId);
this.paymentData = <PaymentData>this.task.actionData;
const incompleteOptionalTasks = this.workflowService.getIncompleteOptionalTasks();
const nextRequiredTask = this.getIncompleteRequired();
this.nextTask = nextRequiredTask;
if (!nextRequiredTask amp;amp; incompleteOptionalTasks) {
this.nextTask = this.tasks.find(task => task.id !== this.paymentId);
} else if (nextRequiredTask) {
this.nextTask = nextRequiredTask;
}
});
Поскольку во втором наблюдаемом объекте есть switchMap
, я довольно растерян. Я начал пытаться выписать concatMap
для этих двух:
this.workflowService.getFolderActions().pipe(
tap(tasks => this.tasks = tasks),
concatMap(tasks => {
this.route.data.pipe(
switchMap(x => {
return this.route.paramMap;
})
)
})
);
… но я получаю сообщение об ошибке: 'tasks' is declared but its value is never read.
Однако я уверен, что я неправильно подхожу к этому, поэтому любая помощь будет высоко оценена.
Ответ №1:
Рассмотрите возможность его реализации следующим образом:
this.workflowService.getFolderActions().
pipe(
tap(tasks => this.tasks = tasks),
switchMapTo(this.route.paramMap)
)
.subscribe(params => {
this.paymentId = params.get('id');
this.task = this.workflowService.getTask(this.paymentId);
this.paymentData = <PaymentData>this.task.actionData;
const incompleteOptionalTasks = this.workflowService.getIncompleteOptionalTasks();
const nextRequiredTask = this.getIncompleteRequired();
this.nextTask = nextRequiredTask;
if (!nextRequiredTask amp;amp; incompleteOptionalTasks) {
this.nextTask = this.tasks.find(task => task.id !== this.paymentId);
} else if (nextRequiredTask) {
this.nextTask = nextRequiredTask;
}
});
При необходимости вы можете захотеть получить tasks
в функции подписки вместо сохранения ее глобально:
this.workflowService.getFolderActions().
pipe(
tap(tasks => this.tasks = tasks),
withLatestFrom(this.route.paramMap)
)
.subscribe(([tasks, params]) => {
this.paymentId = params.get('id');
this.task = this.workflowService.getTask(this.paymentId);
this.paymentData = <PaymentData>this.task.actionData;
const incompleteOptionalTasks = this.workflowService.getIncompleteOptionalTasks();
const nextRequiredTask = this.getIncompleteRequired();
this.nextTask = nextRequiredTask;
if (!nextRequiredTask amp;amp; incompleteOptionalTasks) {
this.nextTask = tasks.find(task => task.id !== this.paymentId);
} else if (nextRequiredTask) {
this.nextTask = nextRequiredTask;
}
});
Комментарии:
1. Вау, это так невероятно полезно — я не был так хорошо знаком с операторами
withLatestFrom
иswitchMapTo
— читаю о них сейчас. Большое вам спасибо, я действительно ценю помощь!
Ответ №2:
В вашем случае switchMap
оператор выбран правильно, потому что он имеет доступ к значению из первого наблюдаемого, где вы можете оперировать этим значением, а затем вы также должны вернуть наблюдаемое.
this.workflowService.getFolderActions()
.pipe(
switchMap((tasks ) => {
this.tasks = tasks;
return this.route.paramMap;
})
.subscribe(() => ...)