Все, коллеги, разобрался. Я не вернул сам промис.
Вот такой код работает:
let range = {
from: 1,
to: 5,
[Symbol.asyncIterator]() {
return {
current: this.from,
last: this.to,
next() {
return new Promise(resolve => setTimeout(resolve, 2000))
.then(() => {
if (this.current <= this.last) {
return { done: false, value: this.current++ }
} else {
return { done: true }
}
})
}
}
}
}
let count = async function() {
for await (let value of range) {
console.log(value);
}
}
count()
И отвечая на доп. вопрос: все же так можно сделать, и это видно из кода выше. Метод then возвращает промис, но с нюансами: если обработчик handler в then(handler) заканчивается возвратом некоторого значения, то возвращенный then промис выполняется с этим значением.
В моем первом случае обработчик возвращал новый промис, и возвращаемый then промис завершался с результатом этого нового промиса, что, собственно, делать было не обязательно и являлось лишним шагом в коде.
Итого: завершенный с некоторым результатом промис возвращается из then, но его надо вернуть из next().