Задать вопрос
@TicSo

Как правильно вывести данные из функции в див?

Как поправить код,
чтобы тестовый нерабочий вариант вывода числа для дива id="d1"
заработал для дива id="d2"
/* html:
   <div id="d1" style="height: 30px; width: 80px; background-color: yellow;"></div>
   <div id="d2" style="height: 30px; width: 80px; background-color: orange;"></div>
*/
// js:
document.getElementById("d1").innerHTML = getNum();
function getNum(){ 
    let a;
    setTimeout(function(){a = 5;}, 2000);
    return a;
}

document.getElementById("d2").innerHTML = loadNum();
async function loadNum() {
   let a;
   // let result = await ... ;
   let result = setTimeout(function() {a = 55;}, 2000);
   console.log("лог = " + result);
   // return result;
   return ...;
}

/*
(async function(){
  let info = await loadNum();
  console.log("info = " + info);
})();
*/
  • Вопрос задан
  • 92 просмотра
Подписаться 1 Средний 2 комментария
Помогут разобраться в теме Все курсы
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
  • Академия Эдюсон
    Fullstack-разработчик на JavaScript + ИИ
    11 месяцев
    Далее
  • ProductStar × РБК
    Профессия: Инженер по тестированию + ИИ
    6 месяцев
    Далее
Решения вопроса 3
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Вы не понимаете логику асинхронности в JS.
Когда родительская функция вызывает setTimeout, ядро JS создаёт таймер и привязывает к нему ссылку на функцию и окружение. После этого родительская функция продолжает свою работу. При срабатывании таймера, привязанная к нему функция с окружением помещается в очередь макрозадач и выполняется, когда до неё дойдёт очередь. Как правило, родительская функция к тому моменту давно уже завершилась.
Примерно то же самое выполняется для любой асинхронной функции с тем исключением, что функции-обещания (Promise) помещаются в приоритетную очередь микрозадач.
Ваш код
function getNum(){ 
    let a;
    setTimeout(function(){a = 5;}, 2000);
    return a;
}
выполняется как
// Вызов getNum()
let a;
setTimeout(fn, 2000); // Здесь создаётся таймер с привязанной функцией и лексическим окружением, сама функция не вызывается
return a;
...
// Сработал таймер, fn помещена в очередь
// Вызов fn
a = 5;


P.S. Да, в JS фактически один поток выполнения задачи и служебные потоки для таймеров, ввода/вывода и прочих задач ядра. Полноценного параллелизма в нём нет, все функции основного потока выполняются только по очереди.
Ответ написан
Комментировать
opium
@opium
Просто люблю качественно работать
`setTimeout` не Promise — он возвращает id таймера, поэтому `a` остаётся `undefined` к моменту `return`.

Оберни в Promise:

async function loadNum() {
  return new Promise(resolve => setTimeout(() => resolve(55), 2000));
}

(async () => {
  document.getElementById("d2").innerHTML = await loadNum();
})();


Или через `.then()`:
loadNum().then(n => document.getElementById("d2").innerHTML = n);
Ответ написан
@alexalexes
Такие упражнения, обычно, предлагают выполнить, чтобы понять боль отсутствия async/await в ранних стандартах языка JS.
Если решать задачу по старинке, то вам нужно тащить ссылку на элемент внутрь callback функции (и остальной контекст некоторых переменных) , чтобы в нужный момент наполнить элемент содержимым:
var d2_elem = document.getElementById("d2");
var d2_func = (function(elem, a) {
  return function() {
     // В этой области мы заморозили замыканием и ссылку на элемент, и значение a.
     elem.innerHTML = a;
  }
})(d2_elem, 55);
loadNum(d2_func); // ссылка на функцию d2_func содержит в себе замороженные d2_elem и 55, теперь можно эту функцию использовать для отложенного вызова или вызывать по какому-нибудь событию
function loadNum(callback) {
   setTimeout(callback, 2000);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы