Реализация массива Rubico `map.pool` - PullRequest
0 голосов
/ 27 мая 2020

Это map.pool моей библиотеки асинхронной композиции функций, rubico .

Вы могли бы использовать это так; sleepThenDo - игрушечная функция, используемая для тестирования. map.pool

const { map } = require('rubico')

const sleepThenDo = (ms, fn) => x => new Promise(resolve => {
  setTimeout(() => {
    fn(x)
    resolve()
  }, ms)
})

map.pool(2, sleepThenDo(1000, console.log))([1, 2, 3, 4, 5, 6]) /*
*waits a bit*
1
2 
*waits a bit*
3
4
*waits a bit*
5
6
*/

Это реализация. Затем вызывается

const mapPoolIndexedWorker = insert => (size, fn, resolve, reject, x, y, i) => {
  if (i >= x.length) return
  if (reject._called) return
  let point
  try {
    point = fn(x[i])
  } catch (err) {
    reject._called = true
    return reject(err)
  }
  if (isPromise(point)) {
    point.then(res => {
      insert(y, res, i)
      if (i === x.length - 1) {
        resolve(y)
      } else {
        mapPoolIndexedWorker(insert)(size, fn, resolve, reject, x, y, i + size)
      }
    }).catch(err => {
      reject._called = true
      reject(err)
    })
  } else {
    insert(y, point, i)
    if (i === x.length - 1) {
      resolve(y)
    } else {
      mapPoolIndexedWorker(insert)(size, fn, resolve, reject, x, y, i + size)
    }
  }
}

const mapPoolArrayWorker = mapPoolIndexedWorker((y, xi, i) => { y[i] = xi })

const mapPoolArray = (size, fn, x) => new Promise((resolve, reject) => {
  if (x.length < 1) return resolve([])
  const y = []
  for (let i = 0; i < Math.min(x.length, size); i++) {
    mapPoolArrayWorker(size, fn, resolve, reject, x, y, i, i) // start off the workers
  }
})

mapPoolArray, если аргумент данных является массивом.

Возможна ли утечка памяти? Это, конечно, работает, но я хочу знать, можно ли с точки зрения памяти думать таким образом о «пуле» рабочих. Я также хотел бы знать, есть ли способ гарантировать массив PACKED при возврате

...