#typescript #rxjs #nestjs
Вопрос:
Я хочу вернуть недавно обновленный объект. Но когда я пытаюсь присвоить значения с помощью методов с цепочкой каналов, это не работает и возвращает начальные значения.
Как лучше всего назначать с помощью цепных функций и возвращать объект ?
Вот код:
currentUser: UserInterface = {
accessToken: '',
userID: '',
name: '',
email: '',
picture: '',
pageList: [],
activePageID: 0,
activePage: {
name: '',
pageID: '',
instagramID: '',
categoryID: '',
tasks: [],
},
};
login(user: FacebookLoginInterface) {
this.generateLongUserToken(user.accessToken).pipe(
map((response) => {
this.currentUser.accessToken = response.access_token;
this.getUserPages(this.currentUser.accessToken).pipe(
map((response) => {
this.currentUser.pageList = response;
this.getInstagramBusinessAccount(
this.currentUser.pageList[0].id,
this.currentUser.accessToken,
).pipe(
map((response) => {
this.currentUser.activePage.instagramID =
response.instagram_business_account.id;
}),
);
}),
);
}),
);
return {
access_token: this.currentUser,
};
}
Комментарии:
1. Что именно такое «метод с цепочкой из труб». Насколько мне известно, это не собственная концепция javascript/машинописного текста.
2. «Труба» также не является концепцией NextJS. По крайней мере, я этого не знаю… Ты звонишь
this.generateLongUserToken(user.accessToken)
. Что возвращает этот метод?3. @Elias Я развиваюсь в «nestjs». Он возвращает новый токен с длительным сроком действия, когда я даю токен с коротким сроком действия. Что я хочу, так это: есть 2-3 метода, которые возвращают значения из api facebook. И мне нужно назначить их своим коллегам в «CurrentUser». Но он не ждет, пока они закончат, и мгновенно возвращает «текущего пользователя», или назначение аналогов в методах не работает.
4. Mh, какой тип текста он возвращает?
5. Если
this.generateLongUserToken(user.accessToken)
возвращаетUserInterface
, не должно ли бытьpipe
функции в этом интерфейсе?
Ответ №1:
Используйте обещания
login() {
return new Promise((resolve, reject) => {
this.generateLongUserToken(user.accessToken).pipe(
map((response) => {
this.currentUser.accessToken = response.access_token;
this.getUserPages(this.currentUser.accessToken).pipe(
map((response) => {
this.currentUser.pageList = response;
this.getInstagramBusinessAccount(
this.currentUser.pageList[0].id,
this.currentUser.accessToken,
).pipe(
map((response) => {
this.currentUser.activePage.instagramID =
response.instagram_business_account.id;
// If I understand correctly, at this point `currentUser`
// is ready to be returned, so resolve the promise here
resolve()
}),
);
}),
);
}),
);
}).then(() => ({
access_token: this.currentUser,
}))
}
currentUser.login().then(user => {
// Here user is updated
})
Кроме того, вы могли бы немного очистить его, чтобы иметь меньше уровней вложенности
login() {
return new Promise((resolve) => {
this.generateLongUserToken(user.accessToken).pipe(
map((response) => {
this.currentUser.accessToken = response.access_token;
resolve(response.access_token)
})
)
}).then((accessToken) => new Promise((resolve) => {
this.getUserPages(this.currentUser.accessToken).pipe(
map((response) => {
this.currentUser.pageList = response;
resolve({pageList: response, accessToken})
})
)
})).then(({pageList, accessToken}) => new Promise(resolve => {
this.getInstagramBusinessAccount(
this.currentUser.pageList[0].id,
this.currentUser.accessToken,
).pipe(
map((response) => {
this.currentUser.activePage.instagramID =
response.instagram_business_account.id;
resolve()
})
)
})).then(() => ({
access_token: this.currentUser,
}))
}
За исключением того, что это будет работать только в том случае, если функция in map
будет вызвана один раз. Название map
предполагает, что обратный вызов может быть вызван несколько раз, в этом случае это также не сработает. В любом случае, вы должны использовать обещания