Я хотел бы иметь возможность рассуждать о том, что будет делать await
, когда он вызывается для различных значений.
Документация MDN для await описывает процедуру принятия решения, один из шагов которой заключается в том, чтобы решить, является ли объект thenable
(после того, как он определил, что это не Native Promise):
Выражение разрешается так же, как и Promise.resolve(): оно всегда преобразуется в собственный Promise, а затем ожидается. Если выражение представляет собой:
- Родное обещание [...]
- Затем объект (включая неродные промисы, полифилл, прокси, дочерний класс и т. д.): [...]
- [...]
(И связанный документ для Promise.resolve() также говорит по существу
то же самое — в частности, он ссылается на тот же раздел Thenable object
в документации Promise).
Итак, переходя по этой ссылке на объект Thenable, мы все еще ищем точное определение Thenable object
, как оно используется в процедуре принятия решения (т. е. как именно await
и Promise.resolve()
проверяют его в этой процедуре принятия решения):
thenable реализует метод .then(), который вызывается с двумя обратными вызовами: один, когда обещание выполнено, другой, когда оно отклонено.
Это самое близкое к ответу на этой странице, но это не ответ.
(Например, считается ли вещь, которая, как известно, не является Native-Promise, управляемой, если попытка получить ее свойство then
не выдает выдачу? Или она не выдает и не возвращает не неопределенное значение? Или, не выбрасывает и не возвращает что-то, чья typeof
равна function
? Или не выбрасывает и возвращает что-то такое, что вызов с двумя обратными вызовами не выдает и т. д.; есть много возможностей, и я уверен, что это правильно? где-то в спецификации.)
Мой конкретный вопрос: как именно await
и Promise.resolve()
решают, рассматривать ли свой аргумент (как только решено, что это не-Native-Promise) как Thenable object
для целей процедуры принятия решения, указанной выше?
(Примечание: этот вопрос касается оператора ES8 await
и обещаний ES6; речь идет не о bluebird, обещаниях/A+ или любых других реализациях/спецификациях обещаний, поэтому предыдущие вопросы/ответы по ним неприменимы.)
Посмотрите здесь или там
Считается ли вещь допустимой тогда и только тогда, когда попытка получить ее свойство
then
не выбрасывает и не возвращает что-то, чьеtypeof
естьfunction
?
Да, очень то. Вы можете найти это в §27.2.1.3.2 Функции разрешения обещаний , процедуре разрешения обещания со значением, которое используется new Promise
, Promise.resolve
и (в расширении) await
. Это по-прежнему соответствует процедуре Promises/A+ и ее определению «тогда возможно».
Я понимаю. С тем нюансом, что (если я правильно читаю), если попытка получить свойство then
выдает ошибку, то это не делает его неприемлемым для целей этой процедуры принятия решения; скорее, это превращается в «отклонено». Похоже, спецификация очень нужна, чтобы ответить на этот вопрос; это описание страницы MDN служит приблизительным описанием поведения, но оно даже близко не помогает ответить на него в конкретных случаях.
Ну, если доступ к then
выдает ошибку, это не метод… И вообще, любые исключения во время процедуры разрешения превращаются в отклонения, ничем не отличается для обратного вызова исполнителя конструктора, метода доступа .then
или фактического вызова метода.
Это звучит как хороший способ подумать об этом и запомнить его, хотя я не вижу, чтобы этот общий принцип был указан где-либо на этих трех страницах MDN или в разделе спецификаций, на который вы указали. Это где-то конкретно в спецификации или документации? Или нужно просто сделать вывод, прочитав все конкретные пункты и/или зная обоснование этих пунктов спецификации?
Я бы сказал, что это просто общее обоснование того, что игнорировать исключения — это плохо, а превращать их в отклонения — разумный поступок.