Думаю, мне наконец-то удалось сконцентрироваться на javascript/ES6 Promises, по большей части. Это было нелегко! Но что-то меня смущает в дизайне.
Почему конструктор Promise принимает обратный вызов? Учитывая, что обратный вызов вызывается немедленно, не может ли вызывающая сторона просто выполнить этот код вместо этого, тем самым избегая одного ненужного уровня умопомрачительного «не звони мне, я позвоню тебе»?
Вот то, что я считаю прототипом использования Promise, скопированное из учебника Джейка Арчибальда по Javascript Promises http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promisifying-xmlhttprequest с удаленными комментариями.
Это оболочка на основе Promise для XMLHttpRequest GET-запроса:
function get(url) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
if (req.status == 200) {
resolve(req.response);
}
else {
reject(Error(req.statusText));
}
};
req.onerror = function() {
reject(Error("Network Error"));
};
req.send();
});
}
Для меня приведенный выше код был бы намного проще для понимания, если бы он был переписан следующим образом, используя немного другой тип обещания, который я себе представляю, имея конструктор без аргументов и методы разрешения/отклонения:
function get(url) {
var promise = new MyEasierToUnderstandPromise();
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
if (req.status == 200) {
promise.resolve(req.response);
}
else {
promise.reject(Error(req.statusText));
}
};
req.onerror = function() {
promise.reject(Error("Network Error"));
};
req.send();
return promise;
}
MyEasierToUnderstandPromise не так уж сложно реализовать с точки зрения Promise. Сначала я попытался сделать его настоящим подклассом Promise, но по какой-то причине не смог заставить это работать; поэтому вместо этого я реализовал его как простую фабричную функцию, которая возвращает простой старый объект Promise с парой присоединенных дополнительных функций, которые ведут себя как функции-члены:
function NewMyEasierToUnderstandPromise() {
var resolveVar;
var rejectVar;
var promise = new Promise(function(resolveParam, rejectParam) {
resolveVar = resolveParam;
rejectVar = rejectParam;
});
promise.resolve = resolveVar;
promise.reject = rejectVar;
return promise;
};
Итак, почему Promise не разработан таким образом? Я думаю, что если бы это было так, то это помогло бы мне понять Promises намного быстрее — держу пари, это сократило бы мое время обучения вдвое.
Я знаю, что много умных людей приложили руку к созданию Promise API, и все, кажется, в целом счастливы и гордятся этим, поэтому мне интересно, что они думали.