#javascript #es6-promise
#javascript #es6-обещание
Вопрос:
У меня есть этот код:
return (entity.User.getProjects(req.user.id, ....))
.then((list) => {
// party with list object!
return {
list: list
}
}
И я также хочу вызвать другой метод, entity.Tag.getAllForUser
который возвращает tags
список.
(ОБНОВЛЕНИЕ: мне нужно сделать это, используя только обещания — я не могу использовать async / await.)
Этот код не работает — он говорит, что оба list
и tag
не определены:
return (entity.User.getProjects(req.user.id, ....))
.then((list) => entity.Tag.getAllForUser(req.user.id))
.then((list, tags) => {
// party with both list and tags objects!
return {
list: list,
tags: tags
}
}
Я также пытался связать второй вызов с первым:
return (
entity.User.getProjects(req.user.id, ....).then((list) =>
entity.Tag.getAllForUser(req.user.id))
).then((list, tags) => {
// party with both list and tags objects!
return {
list: list,
tags: tags
}
}
Но опять же, там говорится, что list
не определено. Что работает?
Комментарии:
1. Почему у вас несколько возвратов?
2. @chevybow потому что я делаю это неправильно.
3. В вашем заголовке написано «цепные методы», но зачем вам вообще нужно связывание ?
4. @trincot Возможно, я этого не делаю! Мне нужно выполнить оба и использовать результаты обоих. Извините, что не выразился точнее.
Ответ №1:
Это зависит от того, являются ли ваши запросы независимыми или нет:
Получение нескольких разрешенных значений по независимым запросам:
Допустим, у меня есть getUsers()
и getCities()
, и оба независимы (вам не нужны пользователи, чтобы получать города и наоборот). Затем вы можете использовать Promise.all
:
Promise.all([getUsers(), getCities()])
.then(result => {
// result here will be an array of two elements:
// result[0] -> what getUsers resolves
// result[1] -> what getCities resolves
});
Получение нескольких разрешенных значений по зависимым запросам:
Если у вас есть, скажем, getUser()
, который возвращает пользователя, а затем getCouple(user)
, который возвращает человека, связанного с пользователем, а затем getHouse(user1, user2)
, которому, оказывается, нужны оба из них, вы можете сделать следующее:
const user = getUser();
const couple = user.then(u => getCouple(u)); // you can reuse a promise. This does not trigger then handler again, if
// the promise is settled will yield the settle value.
const house = user.then(u => {
return couple.then(c => {
return getHouse(u,c);
});
});
Это становится намного приятнее с async / await:
async function() {
const user = await getUser();
const couple = await getCouple(user);
const house = await getHouse(user, couple);
}
Комментарии:
1. Спасибо! Это самое ясное объяснение, которое я где-либо видел
![]()
Ответ №2:
Лучшим решением здесь является Promise.all
, которое принимает список обещаний и возвращает список разрешенных значений:
return Promise.all([
entity.User.getProjects(req.user.id),
entity.Tag.getAllForUser(req.user.id);
])
.then(([ list, tags ]) => {
// Party!
return { list, tags };
});
Обязательная рекомендация использовать async
и await
:
let [ list, tags ] = await Promise.all([
entity.User.getProjects(req.user.id),
entity.Tag.getAllForUser(req.user.id);
]);
return { list, tags };
Ответ №3:
Просто используйте Async/Await
let list = await entity.User.getProjects(req.user.id, ....))
let tags = await entity.Tag.getAllForUser(req.user.id))
return {
list: list,
tags: tags
}
}
Если вы не можете использовать Async/Await
(хотя я рекомендую их использовать), вы можете использовать promise.all
Promise.all([
entity.User.getProjects(req.user.id),
entity.Tag.getAllForUser(req.user.id);
]).then(([list,tag])=>{
// do here whatever you want
})
Комментарии:
1. Спасибо! Это был бы самый простой способ, но, к сожалению, я не могу этого сделать, потому что кодовая база, в которой я работаю, не позволяет этого. (Обновил вопрос, чтобы прояснить это.)
2. @Richard вы можете использовать,
promise.all
хотя я все равно буду рекомендовать использоватьasyc/await
, что делает код более читаемым и простым в обслуживании.
Ответ №4:
Отвечая на мой собственный вопрос. Пожалуйста, не удаляйте, так как это может быть полезно для кого-то другого!
return (entity.User.getProjects(req.user.id, ....))
.then((list) => Promise.all([list, entity.Tag.getAllForUser(req.user.id)]))
.then(([list, tags]) => {
// party with both list and tags objects!
return {
list: list,
tags: tags
}
}
Комментарии:
1. Я рекомендую использовать
Promise.all
для одновременного выполнения обоих запросов! Ваше решение здесь будет излишне запускать вещи последовательно.