Каковы различия между отложенным, обещанием и будущим в JavaScript?

StackOverflow https://stackoverflow.com/questions/6801283

Вопрос

Каковы различия между отложенными, обещаниями и будущим?
Есть ли в целом утвержденная теория всех этих трех?

Это было полезно?

Решение

В свете очевидной неприязни к тому, как я попытался ответить на вопрос ОП. Литеральный ответ - обещание - это то, что разделяется с другими объектами, в то время как отсроченное должно быть частным. В первую очередь, отложенная (которая, как правило, распространяет обещание) может разрешить себя, в то время как обещание не сможет этого сделать.

Если вы заинтересованы в мелочах, а затем осмотрите Обещания/A+.


Насколько мне известно, всеобъемлющей целью является улучшение ясности и ослабить связь через стандартизированный интерфейс. Видеть Предлагаемое чтение от @jfriend00:

Вместо того, чтобы непосредственно передавать обратные вызовы функциям, что может привести к жестко связанным интерфейсам, использование обещаний позволяет отделять проблемы для кода, который является синхронным или асинхронным.

Лично я обнаружил, что отложено особенно полезным при работе с шаблонами, например, заполненными асинхронными запросами, загрузкой сценариев, которые имеют сети зависимостей, и предоставляя отзывы пользователей для формирования данных не блокирующим образом.

Действительно, сравните чистую форму обратного вызова, что сделает что -то после загрузки кодового асинхронного в режиме 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.");
   });
});

Приносим извинения за полупейдо-код, но я надеюсь, что это прояснит основную идею. По сути, возвращая стандартизированное обещание, вы можете передать обещание, что позволяет получить более четкую группировку.

Другие советы

Эти ответы, в том числе выбранный ответ, хороши для концептуального представления обещаний, но не имеют особенности того, что именно различия в терминологии, которая возникает при использовании их реализации (и тамнаходятся важные различия).

Поскольку это все еще развивающаяся спецификация, ответ в настоящее время приходит в результате попыток осмотреть обе ссылки (например, Википедия) и реализации (например jQuery):

  • Отсрочен: Никогда не описано в популярных ссылках, 1 2 3 4 но обычно используется реализациями в качестве арбитра разрешения обещаний (реализация resolve а также reject). 5 6 7

    Иногда отложенные также являются обещаниями (внедрение then), 5 6 В других случаях он считается более чисты then. 7

  • Обещать: Самое всеобъемлющее слово для обсуждаемой стратегии.

    Прокси -объект, хранящий результат целевой функции, синхронность которой мы хотели бы абстрагировать, плюс разоблачение then Функция принимает другую целевую функцию и возвращает новое обещание. 2

    Пример от Commonjs:

    > asyncComputeTheAnswerToEverything()
        .then(addTwo)
        .then(printResult);
    44
    

     

    Всегда описывается в популярных ссылках, хотя никогда не указано, что разрешение ответственности подлежит чьему разрешению. 1 2 3 4

    Всегда присутствует в популярных реализациях и никогда не давал разрешения абилитов. 5 6 7

  • Будущее: Казалось бы, устаревший термин, найденный в некоторых популярных ссылках 1 и, по крайней мере, одна популярная реализация, 8 Но, по -видимому, понизится из -за обсуждения в предпочтении термина «обещание» 3 и не всегда упоминается в популярных введениях в эту тему. 9

    Однако, по крайней мере, одна библиотека использует термин, в целом для абстрагирования синхронности и обработки ошибок, при этом не предоставляя при этом при этом не предоставление then функциональность. 10 Неясно, было ли избежать термина «обещание» преднамеренным, но, вероятно, хороший выбор, так как обещания построены вокруг «затем». 2

использованная литература

  1. Википедия по обещаниям и фьючерсам
  2. Обещания/A+ Spect
  3. Стандарт DOM на обещаниях
  4. Стандартные обещания DOM Spec WIP
  5. Dojo Toolkit DEFERREDS
  6. jQuery Deferreds
  7. Q.
  8. FutureJS
  9. Функциональный раздел JavaScript о обещаниях
  10. Фьючерсы в тестировании интеграции AngularJS

Разное потенциально путает вещи

Что действительно заставило меня щелкнуть для меня это презентация Домениной Деникола.

В Github Gist, он дал описание, которое мне нравится больше всего, это очень кратко:

Смысл обещаний состоит в том, чтобы вернуть нам функциональную композицию и пузырьки ошибок в асинхронном мире.

Другим словом, обещания - это способ, который позволяет нам написать асинхронный код, который почти так же легко писать, как и было синхронно.

Рассмотрим этот пример с обещаниями:

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().

Обратите внимание, что, насколько я знаю, реализация обещания в jQuery нарушена (см. GIST), по крайней мере, начиная с jQuery 1.8.2.
Это предположительно реализует Обещания/а затем, но вы не получите правильную обработку ошибок, которую вы должны, в том смысле, что вся функция «Async Try/Catch» не будет работать. Что жаль, потому что наличие «попробовать/поймать» с асинхронным кодом совершенно круто.

Если вы собираетесь использовать обещания (вы должны попробовать их с помощью своего собственного кода!), Используйте Крис Коваль. Анкет Версия JQuery - это просто какой -то агрегатор обратного вызова для написания чистого кода jQuery, но упускает смысл.

Что касается будущего, я понятия не имею, я не видел этого ни в одном API.

Редактировать: Доменник Деникола на YouTube разговоры о обещаниях из @FarmКомментарий ниже.

Цитата от Майкла Джексона (да, Майкл Джексон) из видео:

Я хочу, чтобы вы сжег эту фразу в своем уме: Обещание - это асинхронная ценность.

Это отличное описание: обещание похоже на переменную из будущего - первоклассная ссылка на то, что в какой -то момент будет существовать (или случиться).

А Обещать представляет прокси для значения, не обязательно известного при создании обещания. Это позволяет вам связывать обработчиков с возможной стоимостью успеха асинхронного действия или причиной неудачи. Это позволяет асинхронным методам возвращать значения, такие как синхронные методы: вместо конечного значения асинхронный метод возвращает обещание иметь значение в какой -то момент в будущем.

https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/promise

А deferred.promise() Метод позволяет асинхронной функции предотвратить вмешательство другого кода с прогрессом или статусом его внутреннего запроса. Обещание раскрывает только отложенные методы, необходимые для прикрепления дополнительных обработчиков или определения состояния (Затем, сделано, не провалится, всегда, труба, прогресс, состояние и обещание), но не те, которые меняют состояние (Разрешить, отклонить, уведомлять, разрешить, отказаться и уведомлять с).

Если цель предоставлена, deferred.promise() Прикрепит на него методы, а затем вернет этот объект, а не создаст новый. Это может быть полезно для прикрепления поведения обещания к объекту, который уже существует.

Если вы создаете отложенные, сохраните ссылку на отсроченную, чтобы его можно было разрешить или отклонить в какой -то момент. Верните только объект обещания через DEFERRED.PROMISE (), чтобы другой код мог зарегистрировать обратные вызовы или проверить текущее состояние.

Просто мы можем сказать, что Обещать представляет значение, которое еще не известно, где Отсрочен представляет работу, которая еще не закончена.


enter image description here

  • А promise представляет значение, которое еще не известно
  • А deferred представляет работу, которая еще не закончена

Обещание является заполнителем для результата, который изначально неизвестен, в то время как отсроченное представляет вычисление, которое приводит к значению.

Ссылка

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top