Які відмінності між відстрочкою, обіцянками та майбутніми?
Чи існує загально затверджена теорія за всіма цими трьома?
Які відмінності між відстрочкою, обіцянками та майбутніми?
Чи існує загально затверджена теорія за всіма цими трьома?
Відповіді:
У світлі явної неприязні до того, як я намагався відповісти на питання ОП. Буквальна відповідь полягає в тому, що обіцянка - це щось спільне з іншими об'єктами, тоді як відкладене слід залишати приватним. Перш за все, відстрочка (яка, як правило, поширює обіцянку) може вирішити себе, тоді як обіцянка цього не зможе зробити.
Якщо вас цікавлять деталі, вивчіть Обіцянки / A + .
Наскільки я знаю, всеохоплююча мета - поліпшити чіткість і послабити зв'язок через стандартизований інтерфейс. Дивіться запропоновані читання від @ jfriend00:
Замість того, щоб безпосередньо передавати зворотні виклики функціям, те, що може призвести до щільно з'єднаних інтерфейсів, використання обіцянок дозволяє розділити проблеми щодо коду, який є синхронним або асинхронним.
Особисто я вважаю, що відкладене особливо корисне при роботі з, наприклад, шаблонами, заповненими асинхронними запитами, завантаженням сценаріїв, які мають мережі залежностей, та наданням відгуків користувачів для формування даних без блокування.
Дійсно, порівняйте чисту форму зворотного виклику щось робити після завантаження CodeMirror в режимі JS асинхронно (вибачте, я не використовував jQuery деякий час ):
/* assume getScript has signature like: function (path, callback, context)
and listens to onload && onreadystatechange */
$(function () {
getScript('path/to/CodeMirror', getJSMode);
// onreadystate is not reliable for callback args.
function getJSMode() {
getScript('path/to/CodeMirror/mode/javascript/javascript.js',
ourAwesomeScript);
};
function ourAwesomeScript() {
console.log("CodeMirror is awesome, but I'm too impatient.");
};
});
До версії сформульованої обіцянки (знову ж таки, вибачте, я не в курсі jQuery):
/* Assume getScript returns a promise object */
$(function () {
$.when(
getScript('path/to/CodeMirror'),
getScript('path/to/CodeMirror/mode/javascript/javascript.js')
).then(function () {
console.log("CodeMirror is awesome, but I'm too impatient.");
});
});
Вибачення за напівпсевдокод, але я сподіваюся, що це робить основну думку дещо зрозумілою. В основному, повертаючи стандартизовану обіцянку, ви можете передавати обіцянку навколо, тим самим забезпечуючи більш чітке групування.
fn(callback, errback)
не є більш щільно пов'язаним або менш корисним ніж fn().then(callback, errback)
- але це неправильний спосіб використання обіцянок у будь-якому випадку. Я особливо ненавиджу $.when
приклад культового вантажу - немає абсолютно жодної причини, щоб у вас не було $.when
функції, яка працювала з зворотними викликами.
Ці відповіді, включаючи обрану відповідь, корисні для введення обіцянок концептуально, але не мають конкретики, які саме відмінності є у термінології, що виникає при використанні бібліотек, що їх реалізують (і є важливі відмінності).
Оскільки це все ще змінюється специфікація , відповідь на даний момент приходить із спроби огляду як посилань (наприклад, wikipedia ), так і реалізацій (як jQuery ):
Відкладено : Ніколи не описано в популярних посиланнях,
1 2 3 4,
але зазвичай використовується реалізаціями як арбітр вирішення обіцянок (впровадження та ).
5 6 7
resolve
reject
Іноді відстрочки також є обіцянками (реалізацією then
),
5 6
інших разів вважається більш чистою можливість мати відкладений лише здатність до вирішення та змушувати користувача отримувати доступ до обіцянки щодо використання .
7
then
Обіцянка : Найповажніше слово для обговорюваної стратегії.
Проксі-об'єкт, що зберігає результат цільової функції, синхронність якої ми хотіли б абстрагувати, плюс викрити then
функцію, яка приймає іншу цільову функцію і повертає нову обіцянку.
2
Приклад з CommonJS :
> asyncComputeTheAnswerToEverything()
.then(addTwo)
.then(printResult);
44
Завжди описується в популярних посиланнях, хоча ніколи не вказується, на чию відповідальність попадає відповідальність. 1 2 3 4
Завжди присутній у популярних реалізаціях і ніколи не надає можливості роздільної здатності. 5 6 7
Майбутнє : здавалося б, застарілий термін, який зустрічається в деяких популярних посиланнях 1 і, принаймні, в одній популярній реалізації, 8, але, здавалося б, припиняється з обговорення, віддаючи перевагу терміну «обіцянка» 3 і не завжди згадується в популярних вступках до цієї теми. 9
Однак принаймні одна бібліотека використовує цей термін загалом для абстрагування синхронності та керування помилками, не надаючи при цьому then
функціоналу.
10
Незрозуміло, якщо уникнення терміну «обіцянка» було навмисним, але, ймовірно, вдалим вибором, оскільки обіцянки будуються навколо «пані».
2
Різниця між обіцянками / A та обіцянками / A +
(TL; DR; Обіцянки / A + здебільшого вирішує двозначності в Обіцяннях / А)
Task
Що насправді змусило мене натиснути це презентація Доменіка Денікола.
У сутичці github він дав опис, який мені найбільше подобається, це дуже стисло:
Сенс обіцянок полягає у тому, щоб повернути нам функціональну композицію та помилки, що виникають у асинхронному світі.
Іншими словами, обіцянки - це спосіб, який дозволяє нам писати асинхронний код, який майже так само просто записати, як ніби він був синхронним .
Розглянемо цей приклад із обіцянками:
getTweetsFor("domenic") // promise-returning async function
.then(function (tweets) {
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
})
.then(doHttpRequest) // promise-returning async function
.then(
function (responseBody) {
console.log("Most recent link text:", responseBody);
},
function (error) {
console.error("Error with the twitterverse:", error);
}
);
Це працює так, ніби ви писали цей синхронний код:
try {
var tweets = getTweetsFor("domenic"); // blocking
var shortUrls = parseTweetsForUrls(tweets);
var mostRecentShortUrl = shortUrls[0];
var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
console.log("Most recent link text:", responseBody);
} catch (error) {
console.error("Error with the twitterverse: ", error);
}
(Якщо це все ще звучить складно, дивіться цю презентацію!)
Щодо відкладеного, це шлях .resolve()
або .reject()
обіцянки. У специфіці Обіцянки / Б вона називається .defer()
. У jQuery це $.Deferred()
.
Зауважте, що, наскільки я знаю, реалізація Promise в jQuery порушена (див. Цю суть), принаймні, як у jQuery 1.8.2.
Він нібито реалізує обіцянки / Thenable , але ви не отримаєте правильного поводження з помилками, у тому сенсі, що вся функція "асинхронна спроба / зловити" не працюватиме. Шкода, адже мати "спробувати / зловити" з асинхронним кодом надзвичайно здорово.
Якщо ви збираєтеся використовувати Promises (ви повинні спробувати їх з власним кодом!), Використовуйте Kris Коваль в Q . Версія jQuery - це лише якийсь агрегатор зворотних викликів для написання більш чистого коду jQuery, але пропускає суть.
Щодо майбутнього, то я не маю уявлення, я не бачив цього в жодному API.
Редагувати: Домонік Денікола на youtube розмовляє на Обіцянки з коментаря @Farm нижче.
Цитата Майкла Джексона (так, Майкл Джексон ) з відео:
Я хочу, щоб ти запалив цю думку в думці: Обіцянка - це асинхронна цінність .
Це чудовий опис: обіцянка - це як змінна з майбутнього - першокласна посилання на щось, що в певний момент буде існувати (або відбуватиметься).
Promise є проксі - сервер для значення не обов'язково відомий , коли створюються обіцянку. Це дозволяє вам пов’язати обробників з можливим значенням успіху або причиною відмови асинхронної дії. Це дозволяє асинхронним методам повертати значення, як синхронні методи: замість остаточного значення асинхронний метод повертає обіцянку мати значення в якийсь момент майбутнього.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
deferred.promise()
Метод дозволяє асинхронна функції для запобігання іншого коду від втручання прогресу або статусом свого внутрішнього запиту. Обіця викриває лише методи відкладені, необхідні для приєднання додаткових обробників або визначення стану ( тоді, зроблено, не вдалося, завжди, передача, прогрес, стан і обіцянка ), але не ті, які змінюють стан ( вирішувати, відхиляти, повідомляти, вирішувати, відхилитиWith та notifyWith ).
Якщо ціль надана, deferred.promise()
приєднає до неї методи, а потім поверне цей об'єкт, а не створює новий. Це може бути корисно для приєднання поведінки Обіцяння до об'єкта, який вже існує.
Якщо ви створюєте "Відкладений", зберігайте посилання на "Відкладений", щоб воно могло бути вирішено або відхилено в якийсь момент. Повертайте лише об’єкт Promise через deferred.promise (), щоб інший код міг реєструвати зворотні дзвінки або перевіряти поточний стан.
Просто ми можемо сказати, що Обіцянка представляє значення, яке ще не відомо, де як Відкладений, представляє роботу, яка ще не закінчена.
promise
являє собою значення, яке ще не відомо deferred
представляє роботу, яка ще не закінченаОбіцянка є заповнювачем для результату, який спочатку невідомий, тоді як відкладене відображає обчислення, що призводить до значення.
Довідково