Answer the question
In order to leave comments, you need to log in
Why is the modified async iterator code not working?
Good day!
There is the following code that asynchronously iterates over the values in an object that we made iterable ourselves:
let range = {
from: 1,
to: 5,
// for await..of вызывает этот метод один раз в самом начале
[Symbol.asyncIterator]() { // (1)
// ...возвращает объект-итератор:
// далее for await..of работает только с этим объектом,
// запрашивая у него следующие значения вызовом next()
return {
current: this.from,
last: this.to,
// next() вызывается на каждой итерации цикла for await..of
async next() { // (2)
// должен возвращать значение как объект {done:.., value :...}
// (автоматически оборачивается в промис с помощью async)
// можно использовать await внутри для асинхронности:
await new Promise(resolve => setTimeout(resolve, 1000)); // (3)
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
}
};
(async () => {
for await (let value of range) { // (4)
alert(value); // 1,2,3,4,5
}
})()
To make an object asynchronously iterable, it must have a Symbol.asyncIterator(1) method.
This method must return an object with a next() method, which in turn returns a promise (2).
The next() method doesn't have to be async, it can be a regular promise-returning method, but async allows you to use await, so it's convenient. Here we just pause for one second (3).
For iteration, we use for await (let value of range) (4), adding "await" after "for". It will call range[Symbol.asyncIterator]() once and then its next() method to get the values.
let range = {
from: 1,
to: 5,
[Symbol.asyncIterator]() {
return {
current: this.from,
last: this.to,
next() {
new Promise(resolve => setTimeout(resolve, 2000))
.then(() => {
if (this.current <= this.last) {
return Promise.resolve({ done: false, value: this.current++ })
} else {
return Promise.resolve({ done: true })
}
})
}
}
}
}
.then(() => {
if (this.current <= this.last) {
return { done: false, value: this.current++ }
} else {
return { done: true }
}
}
Answer the question
In order to leave comments, you need to log in
You didn't actually return the promise. None return
from method next
.)
Everything, colleagues, understood. I didn't return the promise itself.
Here is the code that works:
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()
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question