Я везде искал информацию об обещаниях или 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 определяется как глобальная переменная.) Но это похоже на то, что мой код выполняется в случайном порядке ...



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ваша функция ничего не возвращает. Если вы хотите, чтобы он возвращал 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 => {
// ...
});
Спасибо за предложения. Я добавил возвращаемое значение и попробовал ваш .then, но currentDate все еще не определен ... может быть, мне нужно использовать функции обратного вызова?
Вы уверены, что запрашиваемый вами currentDate - это тот же самый let, который вы назначаете? В вашем коде это локальная переменная (через currentDate), поэтому она не будет видна извне.
currentDate назначается ранее как глобальная переменная. Но я попробовал это с помощью currentDate2 (local) и получил тот же результат undefined.
Если он глобальный, let создает теневую переменную, которую вы назначаете вместо нее. Не делайте этого, удалите деталь let.
Я попробовал без отпуска, но результат тот же. Он просто отказывается ждать, пока getMaxDate вернет значение.
Не забудьте правильно распространять возвращаемые значения, особенно в цепочках обещаний. getAllData() ничего не возвращает.
Еще раз спасибо, оказалось, что это комбинация неправильного возврата значения и отсутствия упаковки всего в Promise.
Посмотрите на ниже: Рабочий пример 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);
});
});
«ожидаемая функция должна возвращать обещание». Асинхронные функции также могут возвращать значения, не являющиеся обещаниями. Они будут автоматически заключены в обработанное обещание.
Большое спасибо за помощь. Однако этот код по-прежнему дает мне тот же неопределенный результат. Должно быть, моя функция getMaxDate слишком долго возвращает данные. Возможно, я попробую другой подход.
Мне нужен более длительный тайм-аут? Или, может быть, обратный вызов?
Лучше всего увидеть вашу функцию getMaxDate. Без этого сложно что-либо посоветовать.
Хорошо, я добавил свою функцию getMaxDate.
Я обновил свой ответ. Надеюсь, это соответствует вашим потребностям. Я смоделировал загрузку с помощью поддельного API.
Да, спасибо! Ключевым моментом было заключить выборку также в обещание, как вы проиллюстрировали.
В дополнение к этому в документации говорится: «Обещание, которое будет разрешено с использованием значения, возвращаемого функцией async, или отклонено с помощью неперехваченного исключения, созданного изнутри функции async». - Разработчик Mozilla. Поэтому, если вам когда-либо понадобится цепочка перехвата / отклонения, отклоняйте перехваченные неперехваченные исключения.