#promise
#обещание
Вопрос:
Я хочу получить значение из обещания, а затем вернуть это значение из функции. Я использую Axios для получения идентификатора пользователя из базы данных. Я читал, что я должен использовать.затем, но он все еще продолжает возвращать ожидающее обещание:
export async function getCurrentUserName(user){
const userName = await http.get(`${apiUrl}/users/me`,user)
.then(user =>{ return user.data.name });
return userName;
}
войти:
userName Promise {pending}
_proto: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "avi"
Ответ №1:
Единственный способ получить значение из promise — с .then()
помощью или с await
помощью .
Вы не можете напрямую вернуть значение из своей функции, потому что ваша функция возвращается ДО того, как асинхронное значение будет готово. Итак, ваша функция должна вернуть обещание, а затем вызывающий должен использовать .then()
или await
для извлечения значения из обещания.
В коде, который вы показываете в своем первом блоке кода, async
функция ВСЕГДА возвращает обещание, поэтому вы не можете это изменить. Любое значение, которое вы return
используете в async
функции, становится разрешенным значением обещания, которое уже было возвращено.
Чтобы помочь вам понять, давайте рассмотрим время событий в вашей функции:
export async function getCurrentUserName(user){
const userName = await http.get(`${apiUrl}/users/me`,user)
.then(user =>{ return user.data.name });
return userName;
}
getCurrentUserName()
вызывается.- Функция вызывает
http.get()
- Интерпретатор видит
await
и приостанавливает выполнениеasync
функции в точке и ожидает, что обещание, возвращенноеhttp.get()
для разрешения / отклонения. - Затем функция возвращает неразрешенное обещание и выполнение в коде после вызова
getCurrentUserName()
continues . Этот вызывающий код получает неразрешенное обещание. Здесь невозможно вернуть значение, потому что значение еще не известно. Вот почему обещание возвращается как заполнитель для будущего значения. - Через
http.get()
некоторое время он разрешает свое обещание, и выполнение вашей функции продолжается. Он выполняет.then()
обработчик для полученияuser.data.name
. - Интерпретатор переходит к строке
return userName;
. Поскольку этоasync
функция, которая уже фактически вернула обещание, этот оператор return запускает то, что ранее разрешенное обещание теперь будет разрешено с установленным разрешенным значениемuserName
. - Вызывающий, который использовал
await
или.then()
ранее возвращал обещание, получит уведомление о том, что обещание теперь разрешено, и они получатuserName
разрешенное значение.
Комментарии:
1. Спасибо за ваше объяснение. Я попробовал этот фрагмент кода, предложенный Фахадом, но он возвращает мне: user’ использовался до его определения. Можете ли вы взглянуть на это? экспортировать const getCurrentUserName = async (user)=> { try { пусть ответ = ожидает http.get(
${apiUrl}/users/me
,user); пусть пользователь = ожидает ответа.json(); } catch(ошибка) { // ловит ошибки как при выборке, так и в response.json alert(ошибка); } }
Ответ №2:
Это решит вашу проблему.
export async function getCurrentUserName(user) {
let userName = await http.get(`${apiUrl}/users/me`,user)
.then(user => {
if (user) {
username = user.data.name
} else {
alert('Failed to data')
}
return userName;
}
Или вы можете использовать блок try и catch.
async getCurrentUserName(user) {
try {
let response = await http.get(`${apiUrl}/users/me`,user);
let user = await response.json();
} catch(err) {
// catches errors both in fetch and response.json
alert(err);
}
}
Или так всякий раз, когда вы отправляете данные, всегда используйте post, а не get
async getCurrentUserName(user) => {
await http.post(`${apiUrl}/users/me`,user)
.then(user =>{ return user.data.name })
.catch(function (error) {
return error;
})()
}
Комментарии:
1. Привет, @Fahad, я попробовал ваши исправления, но я получаю следующую ошибку: ‘user’ использовался до того, как был определен no-use-before-define
2. Я попробовал ваше второе решение. Это дает =мне указанную выше ошибку.