Как ждать результата в JavaScript?

Я везде искал информацию об обещаниях или async / await, но, похоже, они не работают. Мне нужно получить текущую дату из функции запроса, прежде чем я смогу использовать эту дату в последующих функциях. Это мое лучшее предположение:

    // Retrieve current session date
    var currentDate;
    async function getMaxDate() {

        fetch(url).then((data) => {
            return data.json();
        }).then((json) => {

            // This is the date used in queries
            currentDate = json[obj].max.substr(0, 10);
            console.info(currentDate);

            return new Promise(resolve => {
                setTimeout(() => {
                    resolve(currentDate);
                }, 5000);
            });

        }).catch((e) => {
            console.error('There was an error:');
            console.info(e);
        });

    }


  async function getAllData() {
        try {
            currentDate = await getMaxDate();
            await getMarket(currentDate);
            console.info(currentDate);
        } catch (error) {
            console.info('An error occurred.');
        }
    }

    // This function is called when the document is first loaded
    $(function () {
        let promise = getAllData();
    });

Но поведение остается таким же, как с обещанием / async / await, так и без него - currentDate остается неопределенным до нескольких секунд спустя. Я тоже пробовал звонить так:

    getAllData()
        .then(function (currentDate) {
            console.info(currentDate);
        });

Здесь currentDate еще не определен чуть позже. Для дополнительного пояснения - getMaxDate выполняет выборку, которая может быть достаточно медленной, чтобы вызвать эту проблему. Поскольку позже в этой функции console.info (currentDate) выводит правильное значение. (currentDate определяется как глобальная переменная.) Но это похоже на то, что мой код выполняется в случайном порядке ...

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
175
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваша функция ничего не возвращает. Если вы хотите, чтобы он возвращал currentDate, вы должны сделать это явно.

async function getAllData() {
    try {
        let currentDate = await getMaxDate();
        await getMarket(currentDate);
        console.info(currentDate);

        return currentDate;
    } catch (error) {
        console.info('An error occurred.');
    }
}

Возвращаемое значение будет тем, что присваивается либо в случае then, либо в случае await:

let currentDate = await getAllData();

getAllData.then(currentDate => {
  // ...
});

В дополнение к этому в документации говорится: «Обещание, которое будет разрешено с использованием значения, возвращаемого функцией async, или отклонено с помощью неперехваченного исключения, созданного изнутри функции async». - Разработчик Mozilla. Поэтому, если вам когда-либо понадобится цепочка перехвата / отклонения, отклоняйте перехваченные неперехваченные исключения.

Tyler 05.09.2018 18:11

Спасибо за предложения. Я добавил возвращаемое значение и попробовал ваш .then, но currentDate все еще не определен ... может быть, мне нужно использовать функции обратного вызова?

Russ Karlberg 05.09.2018 18:32

Вы уверены, что запрашиваемый вами currentDate - это тот же самый let, который вы назначаете? В вашем коде это локальная переменная (через currentDate), поэтому она не будет видна извне.

tadman 05.09.2018 18:42

currentDate назначается ранее как глобальная переменная. Но я попробовал это с помощью currentDate2 (local) и получил тот же результат undefined.

Russ Karlberg 05.09.2018 19:43

Если он глобальный, let создает теневую переменную, которую вы назначаете вместо нее. Не делайте этого, удалите деталь let.

tadman 05.09.2018 20:24

Я попробовал без отпуска, но результат тот же. Он просто отказывается ждать, пока getMaxDate вернет значение.

Russ Karlberg 05.09.2018 20:39

Не забудьте правильно распространять возвращаемые значения, особенно в цепочках обещаний. getAllData() ничего не возвращает.

tadman 05.09.2018 21:14

Еще раз спасибо, оказалось, что это комбинация неправильного возврата значения и отсутствия упаковки всего в Promise.

Russ Karlberg 05.09.2018 22:42
Ответ принят как подходящий

Посмотрите на ниже: Рабочий пример jsFiddle

let currentDate;
const url = 'https://jsonplaceholder.typicode.com/posts/1';

function getMaxDate() {
  return new Promise(resolve => {
    fetch(url).then(data => {
      return data.json();
    }).then(json => {
      console.info('data from api', json);
      currentDate = new Date(); // here I simulate to get Date
      console.info(currentDate);
      resolve(currentDate);
    }).catch(error => {
      console.error('There was an error:');
      console.info(e);
      reject(error);
    });
  })

}


function getMarket(date) {
  return new Promise(resolve => {
    resolve({
      market: 'US',
      date
    });
  });
}

async function getAllData() {
  try {
    let currentDate = await getMaxDate();
    console.info('getAllData', currentDate);
    return await getMarket(currentDate);
  } catch (error) {
    console.info('An error occurred.');
  }
}

// This function is called when the document is first loaded
$(function () {
  getAllData().
  then(result => {
    console.info('do sth...', result);
  });
});

«ожидаемая функция должна возвращать обещание». Асинхронные функции также могут возвращать значения, не являющиеся обещаниями. Они будут автоматически заключены в обработанное обещание.

Will 05.09.2018 18:18

Большое спасибо за помощь. Однако этот код по-прежнему дает мне тот же неопределенный результат. Должно быть, моя функция getMaxDate слишком долго возвращает данные. Возможно, я попробую другой подход.

Russ Karlberg 05.09.2018 18:49

Мне нужен более длительный тайм-аут? Или, может быть, обратный вызов?

Russ Karlberg 05.09.2018 19:45

Лучше всего увидеть вашу функцию getMaxDate. Без этого сложно что-либо посоветовать.

kbysiec 05.09.2018 20:14

Хорошо, я добавил свою функцию getMaxDate.

Russ Karlberg 05.09.2018 20:31

Я обновил свой ответ. Надеюсь, это соответствует вашим потребностям. Я смоделировал загрузку с помощью поддельного API.

kbysiec 05.09.2018 21:50

Да, спасибо! Ключевым моментом было заключить выборку также в обещание, как вы проиллюстрировали.

Russ Karlberg 05.09.2018 22:12

Другие вопросы по теме