Что касается Promises/A + Specification, в чем разница между терминами "thenable" и "prom"?
Я проверяю спецификацию Promises/A + ", но не могу понять следующие вещи:
В разделе 1. Терминология
1,1. "promise"
- это объект или функция с тогдашним методом, поведение которого соответствует этой спецификации.
1,2. "thenable"
- это объект или функция, которая определяет метод then.
Итак, в чем разница между терминами "thenable"
и "promise"
?
Также в разделе 2.3. Процедура разрешения обещаний,
Процедура разрешения обещаний - это абстрактная операция, принимающая в качестве вклада обещание и значение, которое мы обозначаем как [[Resolve]](promise, x)
.
Итак, мой вопрос:
Почему это обозначается в 2 открытых и закрывающих скобках? Есть ли какое-либо соглашение?
Большое спасибо.
Ответы
Ответ 1
Итак, в чем разница между терминами "thenable" и "prom"?
Я думаю, что раздел, который вы уже цитировали, очень хорошо отвечает:
- Подходящим является объект с методом
then
. Любой объект.
- Обещание - это объект с методом
then
(т.е. thenable) , который соответствует спецификации.
До сих пор так просто. Я думаю, что ваш реальный вопрос: "Почему они отличаются?"
Проблема в том, что, глядя на объект, вы не можете решить, является ли это обещанием.
Возможно, вы сможете сказать, что это обещание, потому что вы можете видеть, что его метод then
реализуется самим вами или кем-то, кому вы доверяете, - библиотека обещаний по вашему выбору. Вы могли бы "видеть" это, потому что объект наследует от вашего прототипа обещания, или вы даже можете сравнить метод, который (по сути) идентичен функции, которую вы определили. Или любой другой метод проверки, достаточный для вас.
Вы могли бы сказать, что это не обещание, потому что у него нет метода then
.
Но что вы делаете с объектом, который реализует then
, но не известно, что это обещание? Это возможно, и будет обрабатываться как таковое.
Спецификация Promises/A + направлена на интероперабельность между реализациями обещаний и использует существование метода .then()
для duck typing, Он задает точный алгоритм о том, как обрабатывать такие thenables (это может быть promises или, по крайней мере, иметь подобное поведение), чтобы вы могли создать реальное, надежное ( "известное" ) обещание от них.
Почему это обозначается в 2 открытых и закрывающих скобках? Есть ли какое-либо соглашение?
Да, спецификации ECMAScript используют этот синтаксис для внутренних методов и свойств:
Имена внутренних свойств заключаются в двойные квадратные скобки [[]].
Эти свойства фактически не должны существовать, они просто используются для описания того, что должно произойти - реализация должна действовать так, как если бы она использовала их. Тем не менее, они полностью абстрактны.
Ответ 2
Это умная попытка упростить взаимодействие promises между различными библиотеками.
Спектр использует термин thenable
всего в нескольких местах. Это один из самых важных (empasis mine):
Процедура разрешения обещаний - абстрактная операция, принимающая в качестве вклада обещание и значение, которое мы обозначаем как [[Resolve]](promise, x)
. Если x является допустимым, он пытается обещать, принимая состояние x, в предположении, что x ведет себя, по крайней мере, как обещание. В противном случае он выполняет обещание со значением x.
Это позволит разработчикам выполнить проверку:
if (typeof(x.then) === 'function') {
// adopt the state of x
} else {
// fulfill promise with value x
}
Если спецификация вместо этого говорит "если х является обещанием, то...", как бы разработчик знал, является ли x
обещанием или нет? Нет никакого практического способа убедиться, что x
соответствует спецификации Promise, просто проверив его.
Разработчик (скажем, библиотека FooPromises
может сделать что-то вроде
if (x instanceof FooPromises.Promise) {
// adopt the state of x
} else {
// fulfill promise with value x
}
и он эффективно отклонит любой promises, исходящий из разных реализаций.
Вместо этого, используя суперпростое определение thenable
в этом условии, которое разработчики могут легко проверить, тривиально сделать эту проверку, и вы позволяете реализациям играть хорошо друг с другом.
Для вас второй вопрос, я не уверен, но моя идея заключалась бы в том, что в обозначении [[Resolve]](promise, x)
подчеркивается, что это абстрактная операция. Если они сбросили скобки и просто сказали Resolve(promise, x)
, это каким-то образом подразумевает, что разработчики должны создать реальную функцию с именем Resolve
и разоблачить ее.
Это не требуется - Resolve
не входит в интерфейс promises '; это лишь часть их поведения, которая была настолько важна, что ей давали имя и отдельный раздел в документах.