Ошибка при выполнении Promise.all (закрыть соединение / положить трубку) - PullRequest
0 голосов
/ 08 мая 2020

Я работаю с пакетом google-spreadsheet@2.0.7, у меня есть много данных для экспорта в Google Sheet,

сейчас я использую этот код

const insertDataToSheet = async (data, sheet, msg) => {
  let query = []
  try {
    data.map(async item => {
      query.push(promisify(sheet.addRow)(item))
    })
    const result = await Promise.all(query)
    if (result) return result
    throw new Error(`${msg} Unkown Error`)
  } catch (e) {
    throw new Error(`${msg} Failed: ${e.message}`)
  }
}

Этот код работает с 100 данных или меньше, но если я использую 150+ данных, соединение не поддерживает его.

Список ошибок

- Client network socket disconnected before secure TLS connection was established
- Socket hang up
- Error: HTTP error 429 (Too Many Requests)

Есть ли какие-либо ограничения для Promise.all.?

или

Есть ли лучшее решение для экспорта пакетных / массовых данных в Google Spreadsheet?

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Наконец, я работаю над этим и узнаю, что есть новая версия пакета. google-spreadsheet@3.0.11.

это изменение с Google Drive API на Google Sheets API. В нем много изменений, но в моем случае теперь я могу вставлять пакетно / массово только одной строкой.

теперь это мой код.

const insertDataToSheet = async (data, sheet, msg) => {
  try {
    const result = await sheet.addRows(data)
    if (result) return result
    throw new Error(`${msg} Unkown Error`)
  } catch (e) {
    throw new Error(`${msg} Failed: ${e.message}`)
  }
}

Я просто использую sheet.addRows и tada он работает.

Моя проблема решена, но, обещаю, мне все еще нужно научиться

Спасибо за все ваши предложения / внимание.

1 голос
/ 08 мая 2020

Promise.all выбросит, если одно из обещаний выбросит. Если вы хотите продолжить, даже если одно обещание не выполняется, вы не хотите повторно использовать его, как в приведенном выше коде.

вы можете повторно добавить его в очередь ожидания и повторить попытку.

Кроме того, я могу рассмотреть возможность его пакетной обработки. разделите их на куски и загрузите.

пример:

создать пул рабочих (количество работ = количество ядер процессора (по умолчанию))

запустить загрузку logi c с рабочим пулом

имитировать ошибку / повторить попытку с помощью Math.random

process.js файла

const path = require('path')
const _ = require('lodash')
const Pool = require('piscina')
const BB = require('bluebird')

const workerPool = new Pool({
    filename: path.resolve(__dirname, 'worker.js'),
})

const generateData = (numItems = 5) => {
    return Array.from({ length: numItems }, (v, idx) => 'item ' + idx)
}

const CHUNK_SIZE = 10
const data = generateData(100)

const chunks = _.chunk(data, CHUNK_SIZE)

BB.map(
    chunks,
    (chunk) => {
        workerPool.runTask(chunk)
    },
    { concurrency: 1 /* 1 chunk at a time */ }
)

worker.js файла

const retry = require('p-retry')

// your upload logic here
function process(data) {
    if (Math.random() > 0.5) {
        console.log('processing ', data)
    } else {
        console.log('fail => retry ', data)
        throw new Error('process failed' + data)
    }
}
module.exports = (data) => {
    return retry(() => process(data), { retries: 10 })
}

запустить с node process.js

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...