[Перевод] Коллбэк в JavaScript… Что за зверь?
Комментарии (9)
14 июня 2017 в 15:38 (комментарий был изменён)
+4↑
↓
Коллбэки в JavaScript для дошкольников? Подобные статьи появляются с определённой периодичностью. Но кто-то хоть не просто выдаёт материал 15-летней давности, а про промисы и async пишут. Хотя и по ним уже уйма статей есть.14 июня 2017 в 15:59 (комментарий был изменён)
0↑
↓
как преобразовать callback:
function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); alert('Stop'); } function alertFinished(){ alert('Finished my homework'); } doHomework('math', alertFinished);
к промисам:
function doHomework(subject) { return new Promise(function(resolve) { alert(`Starting my ${subject} homework.`); resolve(); alert('Stop'); }); } doHomework('math').then(alert('Finished my homework'));
ожидаю выполнение alert ('Stop') после alert ('Finished my homework')
почему работает наоборот?
14 июня 2017 в 16:02
+1↑
↓
Потому что продолжения всегда исполняются асинхронно. Формальное требование для A+/Promises звучит примерно так: «при исполнении продолжения в стеке вызовов не должно быть никаких фреймов кроме инфраструктурных».
14 июня 2017 в 16:22
0↑
↓
вот как можно обойти:
function doHomework(subject) { return new Promise(async function (resolve) { alert(`Starting my ${subject} homework.`); await resolve(); alert('Stop'); }); } doHomework('math').then(alert('Finished my homework'));
14 июня 2017 в 16:29 (комментарий был изменён)
+2↑
↓
В том, что вы написали — нет смысла.
resolve();
ничего не возвращает, а применять к нему await бессмысленно. Аналогично бессмысленно делать функцию, переданную в конструктор Promise, асинхронной — никто не будет проверять что она вернула.Возможно, вам показалось что все работает как вы задумывали из-за нескольких случайностей. Одна из которых — неправильно созданное продолжение (вы вызываете alert сразу же вместо того чтобы передавать его как замыкание).
14 июня 2017 в 16:07 (комментарий был изменён)
+1↑
↓
Если вам нужно исполнение
alert('Stop');
строго после любых прямых продолжений — можно использоватьsetTimeout
:function doHomework(subject) { return new Promise(resolve => { alert(`Starting my ${subject} homework.`); resolve(); }) .then(() => new Promise(resolve => setTimeout(resolve, 0))) .then(() => alert('Stop')); }
Но на самом деле так лучше не делать, ибо костыль. Если вам требуется дождаться окончания исполнения обратного вызова — значит, обещания для этого не подходят.
14 июня 2017 в 16:02
0↑
↓
Как-то припозднились. На дворе уже вовсю промисы и уже разворачивается async/await, а вы про коллбеки.
14 июня 2017 в 17:10
+1↑
↓
Ждём статью про циклы и анонимные функции. Блин, серъёзно, что делает этот пост на хабре в 2017?14 июня 2017 в 17:31
+1↑
↓
весьма распространена калька с оригинального названия: «коллбэк». Если же обойтись без жаргона, то о чём мы говорим, называется «функция обратного вызова».
Справедливости ради калька — это как раз функция «обратного вызова», а «коллбэк» — лексическое заимствование.