ÐÑÐ¸Ð½Ñ ÑоннÑе иÑеÑаÑоÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ Ð¿ÐµÑебиÑаÑÑ Ð´Ð°Ð½Ð½Ñе, поÑÑÑпаÑÑие аÑÐ¸Ð½Ñ Ñонно. ÐапÑимеÑ, когда Ð¼Ñ Ð·Ð°Ð³ÑÑжаем ÑÑо-Ñо по ÑаÑÑÑм по ÑеÑи. ÐÑÐ¸Ð½Ñ ÑоннÑе генеÑаÑоÑÑ Ð´ÐµÐ»Ð°ÑÑ Ñакой пеÑÐµÐ±Ð¾Ñ ÐµÑÑ Ñдобнее.
ÐавайÑе ÑнаÑала ÑаÑÑмоÑÑим пÑоÑÑой пÑимеÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð½ÑÑÑ ÑинÑакÑиÑ, а заÑем â ÑеалÑнÑй пÑакÑиÑеÑкий.
ÐÑÐ¸Ð½Ñ ÑоннÑе иÑеÑаÑоÑÑ
ÐÑÐ¸Ð½Ñ ÑоннÑе иÑеÑаÑоÑÑ Ð¿Ð¾Ñ Ð¾Ð¶Ð¸ на обÑÑнÑе иÑеÑаÑоÑÑ, но имеÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе ÑинÑакÑиÑеÑкие оÑлиÑиÑ.
«ÐбÑÑнÑй» пеÑебиÑаемÑй обÑекÑ, как подÑобно ÑаÑÑказано в главе ÐеÑебиÑаемÑе обÑекÑÑ, вÑглÑÐ´Ð¸Ñ Ð¿ÑимеÑно Ñак:
let range = {
from: 1,
to: 5,
// for..of вÑзÑÐ²Ð°ÐµÑ ÑÑÐ¾Ñ Ð¼ÐµÑод один Ñаз в Ñамом наÑале
[Symbol.iterator]() {
// ...возвÑаÑÐ°ÐµÑ Ð¾Ð±ÑекÑ-иÑеÑаÑоÑ:
// далее for..of ÑабоÑÐ°ÐµÑ ÑолÑко Ñ ÑÑим обÑекÑом, запÑаÑÐ¸Ð²Ð°Ñ ÑледÑÑÑее знаÑение вÑзовом next()
return {
current: this.from,
last: this.to,
// next() вÑзÑваеÑÑÑ Ð½Ð° каждой иÑеÑаÑии Ñикла for..of
next() { // (2)
// должен возвÑаÑаÑÑ Ð·Ð½Ð°Ñение в виде обÑекÑа {done:.., value :...}
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
}
};
for(let value of range) {
alert(value); // 1, поÑом 2, поÑом 3, поÑом 4, поÑом 5
}
ÐÑли нÑжно, пожалÑйÑÑа, ознакомÑÑеÑÑ Ñ Ð³Ð»Ð°Ð²Ð¾Ð¹ пÑо иÑеÑаÑоÑÑ, где обÑÑнÑе иÑеÑаÑоÑÑ ÑазбиÑаÑÑÑÑ Ð¿Ð¾Ð´Ñобно.
ЧÑÐ¾Ð±Ñ ÑделаÑÑ Ð¾Ð±ÑÐµÐºÑ Ð¸ÑеÑиÑÑемÑм аÑÐ¸Ð½Ñ Ñонно:
- ÐÑполÑзÑеÑÑÑ
Symbol.asyncIteratorвмеÑÑоSymbol.iterator. next()должен возвÑаÑаÑÑ Ð¿ÑомиÑ.- ЧÑÐ¾Ð±Ñ Ð¿ÐµÑебÑаÑÑ Ñакой обÑекÑ, иÑполÑзÑеÑÑÑ Ñикл
for await (let item of iterable).
ÐавайÑе Ñоздадим иÑеÑиÑÑемÑй обÑÐµÐºÑ range, как и в пÑедÑдÑÑем пÑимеÑе, но ÑепеÑÑ Ð¾Ð½ бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð°ÑинÑ
Ñонно, по Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð² ÑекÑндÑ:
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
}
})()
Ðак видим, ÑÑÑÑкÑÑÑа Ð¿Ð¾Ñ Ð¾Ð¶Ð° на обÑÑнÑе иÑеÑаÑоÑÑ:
- ЧÑÐ¾Ð±Ñ ÑделаÑÑ Ð¾Ð±ÑÐµÐºÑ Ð°ÑинÑ
Ñонно иÑеÑиÑÑемÑм, он должен имеÑÑ Ð¼ÐµÑод
Symbol.asyncIterator(1). - ÐÑÐ¾Ñ Ð¼ÐµÑод должен возвÑаÑаÑÑ Ð¾Ð±ÑÐµÐºÑ Ñ Ð¼ÐµÑодом
next(), коÑоÑÑй в ÑÐ²Ð¾Ñ Ð¾ÑеÑÐµÐ´Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ð¿ÑомиÑ(2). - ÐеÑод
next()не обÑзаÑелÑно должен бÑÑÑasync, он Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ð±ÑÑнÑм меÑодом, возвÑаÑаÑÑим пÑомиÑ, ноasyncпозволÑÐµÑ Ð¸ÑполÑзоваÑÑawait, Ñак ÑÑо ÑÑо Ñдобно. ÐдеÑÑ Ð¼Ñ Ð¿ÑоÑÑо делаем паÑÐ·Ñ Ð½Ð° Ð¾Ð´Ð½Ñ ÑекÑндÑ(3). - ÐÐ»Ñ Ð¸ÑеÑаÑии Ð¼Ñ Ð¸ÑполÑзÑем
for await (let value of range)(4), добавлÑÑ Â«await» поÑле «for». Ðн вÑзовеÑrange[Symbol.asyncIterator]()один Ñаз, а заÑем его меÑодnext()Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñений.
ÐÐ¾Ñ Ð½ÐµÐ±Ð¾Ð»ÑÑÐ°Ñ ÑпаÑгалка:
| ÐÑеÑаÑоÑÑ | ÐÑÐ¸Ð½Ñ ÑоннÑе иÑеÑаÑоÑÑ | |
|---|---|---|
| ÐеÑод Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸ÑеÑиÑÑемого обÑекÑа | Symbol.iterator |
Symbol.asyncIterator |
next() возвÑаÑÐ°ÐµÑ |
лÑбое знаÑение | пÑÐ¾Ð¼Ð¸Ñ |
| Ð´Ð»Ñ Ñикла иÑполÑзÑйÑе | for..of |
for await..of |
... не ÑабоÑÐ°ÐµÑ Ð°ÑинÑ
ÑонноФÑнкÑии, коÑоÑÑе ÑÑебÑÑÑ Ð¾Ð±ÑÑнÑÑ ÑÐ¸Ð½Ñ ÑоннÑÑ Ð¸ÑеÑаÑоÑов, не ÑабоÑаÑÑ Ñ Ð°ÑÐ¸Ð½Ñ ÑоннÑми.
ÐапÑимеÑ, опеÑаÑÐ¾Ñ ÑаÑÑиÑÐµÐ½Ð¸Ñ (ÑÑи ÑоÑки ...) не бÑÐ´ÐµÑ ÑабоÑаÑÑ:
alert( [...range] ); // ÐÑибка, Ð½ÐµÑ Symbol.iterator
ÐÑо еÑÑеÑÑвенно, Ñак как он Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ Symbol.iterator, как и for..of без await. ÐÐ¼Ñ Ð½Ðµ подÑ
Ð¾Ð´Ð¸Ñ Symbol.asyncIterator.
ÐÑÐ¸Ð½Ñ ÑоннÑе генеÑаÑоÑÑ
Ðак Ð¼Ñ Ñже знаем, в JavaScript еÑÑÑ Ð³ÐµÐ½ÐµÑаÑоÑÑ, и они ÑвлÑÑÑÑÑ Ð¿ÐµÑебиÑаемÑми.
ÐавайÑе вÑпомним генеÑаÑÐ¾Ñ Ð¿Ð¾ÑледоваÑелÑноÑÑи из Ð³Ð»Ð°Ð²Ñ ÐенеÑаÑоÑÑ. Ðн генеÑиÑÑÐµÑ Ð¿Ð¾ÑледоваÑелÑноÑÑÑ Ð·Ð½Ð°Ñений Ð¾Ñ start до end:
function* generateSequence(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
for(let value of generateSequence(1, 5)) {
alert(value); // 1, поÑом 2, поÑом 3, поÑом 4, поÑом 5
}
РобÑÑнÑÑ
генеÑаÑоÑаÑ
Ð¼Ñ Ð½Ðµ можем иÑполÑзоваÑÑ await. ÐÑе знаÑÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾ÑÑÑпаÑÑ ÑинÑ
Ñонно: в for..of Ð½ÐµÑ Ð¼ÐµÑÑа Ð´Ð»Ñ Ð·Ð°Ð´ÐµÑжки, ÑÑо ÑинÑ
ÑÐ¾Ð½Ð½Ð°Ñ ÐºÐ¾Ð½ÑÑÑÑкÑиÑ.
Ðо ÑÑо еÑли нам нÑжно иÑполÑзоваÑÑ await в Ñеле генеÑаÑоÑа? ÐÐ»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑеÑевÑÑ
запÑоÑов, напÑимеÑ.
ÐÐµÑ Ð¿Ñоблем, пÑоÑÑо добавÑÑе в наÑале async, напÑимеÑ, Ð²Ð¾Ñ Ñак:
async function* generateSequence(start, end) {
for (let i = start; i <= end; i++) {
// ÑÑа, можно иÑполÑзоваÑÑ await!
await new Promise(resolve => setTimeout(resolve, 1000));
yield i;
}
}
(async () => {
let generator = generateSequence(1, 5);
for await (let value of generator) {
alert(value); // 1, поÑом 2, поÑом 3, поÑом 4, поÑом 5
}
})();
ТепеÑÑ Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð°ÑинÑ
ÑоннÑй генеÑаÑоÑ, коÑоÑÑй можно пеÑебиÑаÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ for await ... of.
ÐÑо дейÑÑвиÑелÑно оÑÐµÐ½Ñ Ð¿ÑоÑÑо. ÐÑ Ð´Ð¾Ð±Ð°Ð²Ð»Ñем клÑÑевое Ñлово async, и внÑÑÑи генеÑаÑоÑа ÑепеÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ await, а Ñакже пÑомиÑÑ Ð¸ дÑÑгие аÑинÑ
ÑоннÑе ÑÑнкÑии.
С ÑеÑ
ниÑеÑкой ÑоÑки зÑениÑ, еÑÑ Ð¾Ð´Ð½Ð¾ оÑлиÑие аÑинÑ
Ñонного генеÑаÑоÑа заклÑÑаеÑÑÑ Ð² Ñом, ÑÑо его меÑод generator.next() ÑепеÑÑ Ñоже аÑинÑ
ÑоннÑй и возвÑаÑÐ°ÐµÑ Ð¿ÑомиÑÑ.
Ðз обÑÑного генеÑаÑоÑа Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¿Ñи помоÑи result = generator.next(). ÐÐ»Ñ Ð°ÑинÑ
Ñонного нÑжно добавиÑÑ await, Ð²Ð¾Ñ Ñак:
result = await generator.next(); // result = {value: ..., done: true/false}
ÐÑÐ¸Ð½Ñ Ñонно пеÑебиÑаемÑе обÑекÑÑ
Ðак Ð¼Ñ Ñже знаем, ÑÑÐ¾Ð±Ñ ÑделаÑÑ Ð¾Ð±ÑÐµÐºÑ Ð¿ÐµÑебиÑаемÑм, нÑжно добавиÑÑ Ðº Ð½ÐµÐ¼Ñ Symbol.iterator.
let range = {
from: 1,
to: 5,
[Symbol.iterator]() {
return <обÑÐµÐºÑ Ñ next, ÑÑÐ¾Ð±Ñ ÑделаÑÑ range пеÑебиÑаемÑм>
}
}
ÐбÑÑÐ½Ð°Ñ Ð¿ÑакÑика Ð´Ð»Ñ Symbol.iterator â возвÑаÑаÑÑ Ð³ÐµÐ½ÐµÑаÑоÑ, а не пÑоÑÑой обÑÐµÐºÑ Ñ next, как в пÑедÑдÑÑем пÑимеÑе.
ÐавайÑе вÑпомним пÑÐ¸Ð¼ÐµÑ Ð¸Ð· Ð³Ð»Ð°Ð²Ñ ÐенеÑаÑоÑÑ:
let range = {
from: 1,
to: 5,
*[Symbol.iterator]() { // ÑокÑаÑение Ð´Ð»Ñ [Symbol.iterator]: function*()
for(let value = this.from; value <= this.to; value++) {
yield value;
}
}
};
for(let value of range) {
alert(value); // 1, поÑом 2, поÑом 3, поÑом 4, поÑом 5
}
ÐдеÑÑ ÑозданнÑй обÑÐµÐºÑ range ÑвлÑеÑÑÑ Ð¿ÐµÑебиÑаемÑм, а генеÑаÑÐ¾Ñ *[Symbol.iterator] ÑеализÑÐµÑ Ð»Ð¾Ð³Ð¸ÐºÑ Ð´Ð»Ñ Ð¿ÐµÑеÑиÑÐ»ÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñений.
ÐÑли Ñ
оÑим добавиÑÑ Ð°ÑинÑ
ÑоннÑе дейÑÑÐ²Ð¸Ñ Ð² генеÑаÑоÑ, нÑжно замениÑÑ Symbol.iterator на аÑинÑ
ÑоннÑй Symbol.asyncIterator:
let range = {
from: 1,
to: 5,
async *[Symbol.asyncIterator]() { // Ñо же, ÑÑо и [Symbol.asyncIterator]: async function*()
for(let value = this.from; value <= this.to; value++) {
// паÑза Ð¼ÐµÐ¶Ð´Ñ Ð·Ð½Ð°ÑениÑми, ожидание
await new Promise(resolve => setTimeout(resolve, 1000));
yield value;
}
}
};
(async () => {
for await (let value of range) {
alert(value); // 1, поÑом 2, поÑом 3, поÑом 4, поÑом 5
}
})();
ТепеÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¿Ð¾ÑÑÑпаÑÑ Ñ Ð·Ð°Ð´ÐµÑжкой в Ð¾Ð´Ð½Ñ ÑекÑÐ½Ð´Ñ Ð¼ÐµÐ¶Ð´Ñ Ð½Ð¸Ð¼Ð¸.
ÐÑÐ¸Ð¼ÐµÑ Ð¸Ð· ÑеалÑной пÑакÑики
Ðо ÑÐ¸Ñ Ð¿Ð¾Ñ Ð¼Ñ Ð²Ð¸Ð´ÐµÐ»Ð¸ пÑоÑÑÑе пÑимеÑÑ, ÑÑÐ¾Ð±Ñ Ð¿ÑоÑÑо полÑÑиÑÑ Ð±Ð°Ð·Ð¾Ð²Ð¾Ðµ пÑедÑÑавление. ТепеÑÑ Ð´Ð°Ð²Ð°Ð¹Ñе ÑаÑÑмоÑÑим ÑеалÑнÑÑ ÑиÑÑаÑиÑ.
ÐÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ онлайн-ÑеÑвиÑов, коÑоÑÑе пÑедоÑÑавлÑÑÑ Ð´Ð°Ð½Ð½Ñе поÑÑÑаниÑно. ÐапÑимеÑ, когда нам нÑжен ÑпиÑок полÑзоваÑелей, запÑÐ¾Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ð¿ÑедопÑеделÑнное колиÑеÑÑво (напÑимеÑ, 100) полÑзоваÑелей â Â«Ð¾Ð´Ð½Ñ ÑÑÑаниÑÑ», и URL ÑледÑÑÑей ÑÑÑаниÑÑ.
ÐÑÐ¾Ñ Ð¿Ð¾Ð´Ñ Ð¾Ð´ оÑÐµÐ½Ñ ÑаÑпÑоÑÑÑанÑн, и ÑеÑÑ Ð½Ðµ ÑолÑко о полÑзоваÑелÑÑ , а о ÑÑм Ñгодно. ÐапÑимеÑ, GitHub позволÑÐµÑ Ð¿Ð¾Ð»ÑÑаÑÑ ÐºÐ¾Ð¼Ð¼Ð¸ÑÑ Ñаким обÑазом, Ñ Ñазбивкой по ÑÑÑаниÑам:
- ÐÑжно ÑделаÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° URL в виде
https://api.github.com/repos/<repo>/commits. - РоÑÐ²ÐµÑ Ð¿ÑидÑÑ JSON Ñ 30 коммиÑами, а Ñакже Ñо ÑÑÑлкой на ÑледÑÑÑÑÑ ÑÑÑаниÑÑ Ð² заголовке
Link. - ÐаÑем можно иÑполÑзоваÑÑ ÑÑÑ ÑÑÑÐ»ÐºÑ Ð´Ð»Ñ ÑледÑÑÑего запÑоÑа, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¿Ð¾ÑÑÐ¸Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñов, и Ñак далее.
Ðо нам бÑ, конеÑно же, Ñ Ð¾ÑелоÑÑ Ð²Ð¼ÐµÑÑо ÑÑого Ñложного взаимодейÑÑÐ²Ð¸Ñ Ð¸Ð¼ÐµÑÑ Ð¿ÑоÑÑо обÑÐµÐºÑ Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñами, коÑоÑÑе можно пеÑебиÑаÑÑ, Ð²Ð¾Ñ Ñак:
let repo = 'javascript-tutorial/en.javascript.info'; // ÑепозиÑоÑий на GitHub, оÑкÑда бÑаÑÑ ÐºÐ¾Ð¼Ð¼Ð¸ÑÑ
for await (let commit of fetchCommits(repo)) {
// обÑабоÑка коммиÑов
}
ÐÑ Ð±Ñ Ñ
оÑели ÑделаÑÑ ÑÑнкÑÐ¸Ñ fetchCommits(repo), коÑоÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑаÑÑ ÐºÐ¾Ð¼Ð¼Ð¸ÑÑ, Ð´ÐµÐ»Ð°Ñ Ð·Ð°Ð¿ÑоÑÑ Ð²ÑÑкий Ñаз, когда ÑÑо необÑ
одимо. РпÑÑÑÑ Ð¾Ð½Ð° Ñама ÑазбиÑаеÑÑÑ Ñо вÑем, ÑÑо каÑаеÑÑÑ Ð½ÑмеÑаÑии ÑÑÑаниÑ, Ð´Ð»Ñ Ð½Ð°Ñ ÑÑо бÑÐ´ÐµÑ Ð¿ÑоÑÑо for await..of.
С аÑÐ¸Ð½Ñ ÑоннÑми генеÑаÑоÑами ÑÑо доволÑно легко ÑеализоваÑÑ:
async function* fetchCommits(repo) {
let url = `https://api.github.com/repos/${repo}/commits`;
while (url) {
const response = await fetch(url, { // (1)
headers: {'User-Agent': 'Our script'}, // GitHub ÑÑебÑÐµÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº user-agent
});
const body = await response.json(); // (2) оÑÐ²ÐµÑ Ð² ÑоÑмаÑе JSON (маÑÑив коммиÑов)
// (3) СÑÑлка на ÑледÑÑÑÑÑ ÑÑÑаниÑÑ Ð½Ð°Ñ
одиÑÑÑ Ð² заголовкаÑ
, извлекаем еÑ
let nextPage = response.headers.get('Link').match(/<(.*?)>; rel="next"/);
nextPage = nextPage && nextPage[1];
url = nextPage;
for(let commit of body) { // (4) веÑнÑÑÑ ÐºÐ¾Ð¼Ð¼Ð¸ÑÑ Ð¾Ð´Ð¸Ð½ за дÑÑгим, до оконÑÐ°Ð½Ð¸Ñ ÑÑÑаниÑÑ
yield commit;
}
}
}
- ÐÑ Ð¸ÑполÑзÑем меÑод fetch бÑаÑзеÑа Ð´Ð»Ñ Ð·Ð°Ð³ÑÑзки Ñ ÑдалÑнного URL. Ðн позволÑÐµÑ Ð¿Ñи необÑ
одимоÑÑи добавлÑÑÑ Ð°Ð²ÑоÑизаÑÐ¸Ñ Ð¸ дÑÑгие заголовки, здеÑÑ GitHub ÑÑебÑеÑ
User-Agent. - РезÑлÑÑаÑ
fetchобÑабаÑÑваеÑÑÑ ÐºÐ°Ðº JSON, ÑÑо опÑÑÑ-Ñаки меÑод, пÑиÑÑÑийfetch. - ÐÑжно полÑÑиÑÑ URL ÑледÑÑÑей ÑÑÑаниÑÑ Ð¸Ð· заголовка оÑвеÑа
Link. Ðн Ð¸Ð¼ÐµÐµÑ ÑпеÑиалÑнÑй ÑоÑмаÑ, поÑÑÐ¾Ð¼Ñ Ð¼Ñ Ð¸ÑполÑзÑем ÑегÑлÑÑное вÑÑажение. URL ÑледÑÑÑей ÑÑÑаниÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑглÑдеÑÑ ÐºÐ°Ðºhttps://api.github.com/repositories/93253246/commits?page=2, он генеÑиÑÑеÑÑÑ Ñамим GitHub. - ÐаÑем Ð¼Ñ Ð²ÑдаÑм вÑе полÑÑеннÑе коммиÑÑ, а когда они законÑаÑÑÑ â ÑÑабоÑÐ°ÐµÑ ÑледÑÑÑÐ°Ñ Ð¸ÑеÑаÑиÑ
while(url), коÑоÑÐ°Ñ ÑÐ´ÐµÐ»Ð°ÐµÑ ÐµÑÑ Ð¾Ð´Ð¸Ð½ запÑоÑ.
ÐÑÐ¸Ð¼ÐµÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ (показÑÐ²Ð°ÐµÑ Ð°Ð²ÑоÑов коммиÑов в конÑоли):
(async () => {
let count = 0;
for await (const commit of fetchCommits('javascript-tutorial/en.javascript.info')) {
console.log(commit.author.login);
if (++count == 100) { // оÑÑановимÑÑ Ð½Ð° 100 коммиÑаÑ
break;
}
}
})();
ÐÑо именно Ñо, ÑÑо Ð¼Ñ Ñ Ð¾Ñели. ÐнÑÑÑеннÑÑ Ð¼ÐµÑ Ð°Ð½Ð¸ÐºÐ° поÑÑÑаниÑнÑÑ Ð·Ð°Ð¿ÑоÑов ÑнаÑÑжи не видна. ÐÐ»Ñ Ð½Ð°Ñ ÑÑо пÑоÑÑо аÑÐ¸Ð½Ñ ÑоннÑй генеÑаÑоÑ, коÑоÑÑй возвÑаÑÐ°ÐµÑ ÐºÐ¾Ð¼Ð¼Ð¸ÑÑ.
ÐÑого
ÐбÑÑнÑе иÑеÑаÑоÑÑ Ð¸ генеÑаÑоÑÑ Ð¿ÑекÑаÑно ÑабоÑаÑÑ Ñ Ð´Ð°Ð½Ð½Ñми, коÑоÑÑе не ÑÑебÑÑÑ Ð²Ñемени Ð´Ð»Ñ Ð¸Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ полÑÑениÑ.
Ðогда Ð¼Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼, ÑÑо даннÑе бÑдÑÑ Ð¿Ð¾ÑÑÑпаÑÑ Ð°ÑинÑ
Ñонно, Ñ Ð·Ð°Ð´ÐµÑжками, можно иÑполÑзоваÑÑ Ð¸Ñ
аÑинÑ
ÑоннÑе аналоги и for await..of вмеÑÑоfor..of.
СинÑакÑиÑеÑкие ÑазлиÑÐ¸Ñ Ð¼ÐµÐ¶Ð´Ñ Ð°ÑÐ¸Ð½Ñ ÑоннÑми и обÑÑнÑми иÑеÑаÑоÑами:
| ÐеÑебиÑаемÑй обÑÐµÐºÑ | ÐÑÐ¸Ð½Ñ Ñонно пеÑебиÑаемÑй | |
|---|---|---|
| ÐеÑод Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ Ð¸ÑеÑаÑоÑа | Symbol.iterator |
Symbol.asyncIterator |
next() возвÑаÑÐ°ÐµÑ |
{value:â¦, done: true/false} |
пÑомиÑ, коÑоÑÑй завеÑÑаеÑÑÑ Ñ {value:â¦, done: true/false} |
СинÑакÑиÑеÑкие ÑазлиÑÐ¸Ñ Ð¼ÐµÐ¶Ð´Ñ Ð°ÑÐ¸Ð½Ñ ÑоннÑми и обÑÑнÑми генеÑаÑоÑами:
| ÐенеÑаÑоÑÑ | ÐÑÐ¸Ð½Ñ ÑоннÑе генеÑаÑоÑÑ | |
|---|---|---|
| ÐбÑÑвление | function* |
async function* |
generator.next() возвÑаÑÐ°ÐµÑ |
{value:â¦, done: true/false} |
пÑомиÑ, коÑоÑÑй завеÑÑаеÑÑÑ Ñ {value:â¦, done: true/false} |
Рвеб-ÑазÑабоÑке Ð¼Ñ ÑаÑÑо вÑÑÑеÑаемÑÑ Ñ Ð¿Ð¾Ñоками даннÑÑ , когда они поÑÑÑпаÑÑ Ð¿Ð¾ ÑаÑÑÑм. ÐапÑимеÑ, загÑÑзка или вÑгÑÑзка болÑÑого Ñайла.
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ Ð°ÑÐ¸Ð½Ñ ÑоннÑе генеÑаÑоÑÑ Ð´Ð»Ñ Ð¾Ð±ÑабоÑки ÑÐ°ÐºÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ . Также замеÑим, ÑÑо в некоÑоÑÑÑ Ð¾ÐºÑÑжениÑÑ , напÑимеÑ, бÑаÑзеÑÐ°Ñ , еÑÑÑ Ð¸ дÑÑгое API, назÑваемое Streams (поÑоки), коÑоÑÑй пÑедоÑÑавлÑÐµÑ ÑпеÑиалÑнÑе инÑеÑÑейÑÑ Ð´Ð»Ñ ÑабоÑÑ Ñ Ñакими поÑоками даннÑÑ , Ð¸Ñ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ пеÑедаÑи из одного поÑока в дÑÑгой (напÑимеÑ, загÑÑзка из одного иÑÑоÑника и ÑÑÐ°Ð·Ñ Ð¾ÑпÑавка в дÑÑгое меÑÑо).
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)