#javascript #promise
#javascript #обещание
Вопрос:
У меня есть рекурсивная функция, которая рекурсивно корректно преобразует отображенный массив.
const postCommentsRecursive = (author, permlink) => {
return client.database.call('get_content_replies', [author, permlink])
.then(replies => Promise.all(replies.map(r => {
if (r.children > 0) {
return postCommentsRecursive(r.author, r.permlink)
.then(children => {
r.replies = children;
return r;
})
}else {
return r;
}
})))
}
Но когда я добавил другую выборку данных, возврат из then
остается обещанием:
const postCommentsRecursive = (author, permlink) => {
return client.database.call('get_content_replies', [author, permlink])
.then(replies => Promise.all(replies.map(r => {
//NEW CODE START
const votes = client.database
.call('get_active_votes', [r.author, r.permlink])
.then(av => {
return av;
});
r['active_votes'] = votes;
//NEW CODE END
if (r.children > 0) {
return postCommentsRecursive(r.author, r.permlink)
.then(children => {
r.replies = children;
return r;
})
}else {
return r;
}
})))
}
av
это значение массива, отлично. Но когда я добавляю его к объекту из votes
, вместо этого это Promise
.
Каждый replies
дочерний объект по-прежнему преобразуется в значение, но внутри каждого r
, когда я добавляю votes
в r
as r['active_votes'] = votes
, значение, установленное в объекте, является Promise {<resolved>: Array(1)}
.
Я не могу понять, как получить фактическое Array(1)
значение, а не Promise
как значение. Как мне просто получить Array
в качестве значения, а не Promise
?
Спасибо!
Комментарии:
1. Вы не можете избежать обещаний. Как только вы попали внутрь обещания — все остальное также должно быть внутри обещания.
.then
всегда возвращает обещание, поэтому вам нужно передать обработчики.then
для обработки данных.
Ответ №1:
В вашем коде вы присваиваете r.votes
значение Promise
. Вместо этого вам нужно перейти к .then
этому обещанию, если вы хотите изменить r
. (Концептуально это то же самое, что вы делаете в r.children > 0
блоке)
return client.database
.call('get_active_votes', [r.author, r.permlink])
.then(av => {
// mutate r
r.active_votes = av;
// now return it so that this entire promise resolves with `r`
return r;
});
async/await
обычно подобный код становится немного понятнее:
r.active_votes = await client.database
.call('get_active_votes', [r.author, r.permlink])
Комментарии:
1. Вы можете сделать
then
часть этого короче и менее читабельной:.then(av => (r.active_votes = av, r))
2. Куда я могу поместить асинхронную часть ожидания? ожидание не может быть самостоятельным … спасибо. Я думал об async / await, но не смог заставить его применить здесь.
3. Ваше первое решение работает, с некоторыми изменениями (нет возврата к
client.database
части. Большое вам спасибо! 🙂