получить значение из обещания внутри функции

#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;
}
  
  1. getCurrentUserName() вызывается.
  2. Функция вызывает http.get()
  3. Интерпретатор видит await и приостанавливает выполнение async функции в точке и ожидает, что обещание, возвращенное http.get() для разрешения / отклонения.
  4. Затем функция возвращает неразрешенное обещание и выполнение в коде после вызова getCurrentUserName() continues . Этот вызывающий код получает неразрешенное обещание. Здесь невозможно вернуть значение, потому что значение еще не известно. Вот почему обещание возвращается как заполнитель для будущего значения.
  5. Через http.get() некоторое время он разрешает свое обещание, и выполнение вашей функции продолжается. Он выполняет .then() обработчик для получения user.data.name .
  6. Интерпретатор переходит к строке return userName; . Поскольку это async функция, которая уже фактически вернула обещание, этот оператор return запускает то, что ранее разрешенное обещание теперь будет разрешено с установленным разрешенным значением userName .
  7. Вызывающий, который использовал 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. Я попробовал ваше второе решение. Это дает =мне указанную выше ошибку.