Какова правильная терминология для обещаний JavaScript
Я путаюсь с другой терминологией. Насколько я понимаю, обещание может быть:
fulfilled
rejected
pending
settled
resolved
defer
Означает ли решимость решен? или это значит его выполнили? и какого чёрта отсрочить?
3 ответа
Терминология может быть сложной.
Давайте возьмем из спецификации Promises/A+ и соответствующего раздела ES6, что есть 3 состояния:
- в ожидании - обещание еще не приняло значение, его будущее все еще остается неопределенным.
- выполнено - обещание успешно получило значение результата "назначено"
- отклонено - в обещании указана причина, по которой не может быть получен результат, как правило, ошибка.
Термин " урегулированный" является гиперонимом "выполнено" и "отклонено", что означает либо "противоположность ожидающему".
Динамические глаголы " выполнить" и " отклонить" описывают изменение состояния с ожидающего на выполненное или отклоненное. Эти переходы называются исполнением или отказом от обещания.
Это было легко. Теперь решимость - это другой зверь. Иногда оно используется как синоним "выполнения", но лучше понимать его как решение судьбы обещания либо выполненной, либо отвергнутой. Разрешение (редко - урегулирование) обещания означает, что оно покидает ожидающее состояние. Но даже это не является точным - проблема заключается в рекурсивном характере процедуры разрешения обещаний:
- разрешение обещания с "простой" ценностью означает его выполнение
разрешить обещание обещанием (или выполнимым) означает принятие его состояния:
- решение с выполненным обещанием является выполнением
- решение с отклоненным обещанием является отклонением
- решить с ожидающим обещанием означает ждать его разрешения
Да, если обещание выполнено, может даже не быть известно, будет ли оно выполнено или отклонено. Но это означает, что судьба больше не определена, поскольку она связана с обещанием, с которым мы решили (обратите внимание, что вы можете выполнить обещание только один раз).
Игнорируя этот особый случай, решенное обещание обычно означает урегулированное обещание.
Или, чтобы процитировать спецификацию ECMAScript 6:
Обещание разрешается, если оно выполнено или "заблокировано" в соответствии с состоянием другого обещания. Попытка разрешить или отклонить выполненное обещание не имеет никакого эффекта. Обещание не разрешено, если оно не выполнено. Нерешенное обещание всегда находится в состоянии ожидания. Выполненное обещание может быть отложено, выполнено или отклонено.
и какого чёрта отсрочить?
Откладывание результата означает, что вы возвращаете (асинхронное) обещание для результата, а не результат напрямую (синхронно). А также вернуть отложенный отказ вместо синхронного броска.
Обратите внимание, что " defer " также используется в некоторых библиотеках ( Q) в качестве имени метода для построения Deferred
объект - см. этот ответ на Различия между отложенным, обещанием и будущим для хорошего объяснения.
О, и никогда не доверяйте именам переменных: defer
может также быть сокращенным "deferredObject".
Три состояния обещания перечислены в разделе 2.1 спецификации Promises/A+.
Из спецификации:
Итак, вот каждый из терминов, о которых вы спрашивали:
Pending - начальное состояние обещания. Операция, представленная обещанием, еще не была заполнена или отклонена.
Выполнено еще одно из трех обещанных состояний. Это означает, что обещание было выполнено и теперь имеет свою разрешенную стоимость. Операция, представленная обещанием, была успешно завершена.
Отклонено еще одно из трех обещаний. Это означает, что обещание было отклонено и теперь имеет причину отклонения. Операция, представленная обещанием, не смогла получить значение и, следовательно, имеет причину, по которой это не удалось сделать (обычно это код ошибки или объект ошибки, но это может быть что угодно).
Установленный - это термин, который означает, что обещание либо выполнено, либо отклонено (например, оно больше не ожидает рассмотрения), но это не отдельное состояние, а просто описательный термин, указывающий, что оно больше не ожидает рассмотрения.
Разрешенный - это термин, который часто используется для обозначения того же fulfilled
, но два не совсем то же самое. Обещание может быть разрешено с помощью значения, которое приводит к выполнению, или оно может быть разрешено с помощью отклоненного обещания (что приводит к отклонению этого обещания), или оно может быть разрешено с помощью ожидающего обещания (что означает, что теперь он будет ожидать возможного состояние какого-то другого обещания).
Трудно сказать точно, что вы подразумеваете под отсрочкой. Обещания часто классифицируются как deferred
объекты в том смысле, что они представляют собой объект, представляющий действие и результат, отложенный на будущее (это произойдет в будущем). В некоторых реализациях обещаний есть два типа объектов: deferred
объект и promise
объект. Отложенный объект является надмножеством объекта обещания. Оба могут наблюдать, когда действие разрешено или отклонено с помощью .then()
обработчики. Но только deferred
объект может реально изменить состояние на resolved
или же rejected
,
В jQuery вы можете создать отложенный объект с помощью $.Deferred()
, В других реализациях, таких как обещания ES6, у вас просто есть объекты обещаний с обратным вызовом конструктора, который имеет reject
а также resolve
функции. Мир, по-видимому, движется к тому, что будет у ES6.
Пример JQuery, который использует deferred
объект:
function delay(t) {
var defer = $.Deferred();
setTimeout(function() {
defer.resolve();
}, t);
return defer.promise()
}
delay(200).then(function() {
// run my delayed function now
doMyThing();
});
Пример обещания ES6:
function delay(t) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve();
}, t);
});
}
delay(200).then(function() {
// run my delayed function now
doMyThing();
});
" Состояния и судьбы" Доменика Дениколы - это хорошее, содержательное резюме.
Состояния:
- обещание выполнено, если
promise.then(f)
назову ф "как можно скорее" - обещание отклоняется, если
promise.then(undefined, r)
назовем г "как можно скорее" - обещание ожидает выполнения, если оно не выполнено и не отклонено.
Мойры:
- Обещание разрешается, если попытка разрешить или отклонить его не имеет никакого эффекта, т. е. обещание было "заблокировано" либо для выполнения другого обещания, либо было выполнено или отклонено
- обещание является неразрешенным, если оно не разрешено, то есть если попытка разрешить или отклонить его окажет влияние на обещание.
Перейдите по ссылке для получения подробной информации о состоянии и судьбах.