Параллельный асинхронный итератор - возможно ли это? - PullRequest
0 голосов
/ 06 февраля 2020

Прямо сейчас у меня есть следующий код:

import axios from 'axios'

const urls = ['https://google.com', 'https://yahoo.com']

async function* requests() {
  for (const url of urls) {
    yield axios.get(url)
  }
}

;(async () => {
  for await (const n of requests()) {
    console.log(n.config.url) // prints https://google.com and then https://yahoo.com
  }
})()

Таким образом, запросы не будут блокировать один поток узла, но они будут выполняться последовательно. Мне интересно, можно ли было бы изменить код для принудительного параллелизма.

1 Ответ

0 голосов
/ 06 февраля 2020

«Более простым» способом без углублений будет пакетирование их и получение каждой партии с Promise.all

import axios from 'axios'

const urls = [
  'https://jsonplaceholder.typicode.com/todos/1', 
  'https://jsonplaceholder.typicode.com/posts/1',
  'https://jsonplaceholder.typicode.com/users/1',
  'https://jsonplaceholder.typicode.com/comments/1'
]

async function* requests(batchSize = 1) {
  let batchedRequests = [];
  for (const url of urls) {
    batchedRequests.push(axios.get(url));
    if (batchedRequests.length === batchSize) {
      yield Promise.all(batchedRequests);
      batchedRequests = [];
    }
  }
  if (batchedRequests.length) { //if there are requests left in batch
    yield Promise.all(batchedRequests);
  }
}

;(async () => {
  for await (const batch of requests(2)) {
    batch.forEach(n => console.log(n.config.url)) // prints https://google.com and then https://yahoo.com
  }
})()

. Вы можете использовать rxjs для достижения аналогичных результатов с преимуществами, которые имеют наблюдаемые с точки зрения гибкости, но это еще одна библиотека, которая может быть более сложной, если вы не знакомы с реактивными потоками. Вот подробный пост, который я нашел в topi c: https://medium.com/@ravishivt / batch-processing-with-rx js -6408b0761f39

...