【问题标题】:Error when do Promise.all (close connection / hang up)Promise.all 时出错(关闭连接/挂断)
【发布时间】:2020-05-08 07:27:38
【问题描述】:

我正在使用 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 电子表格?

【问题讨论】:

    标签: node.js es6-promise google-sheets-api


    【解决方案1】:

    Promise.all 将抛出一个承诺抛出。如果你想在一个承诺失败的情况下继续,你不想像上面的代码那样重新抛出它。

    您可以将其重新添加到待处理队列并重试。

    另外,我可以考虑批量处理。将它们分成块并上传。

    示例:

    创建一个工作池(工作数 = cpu 核心数(默认))

    使用工作池运行上传逻辑

    使用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运行

    【讨论】:

    • 使用 await promise.all 重试的任何示例 .?
    • 如果你想重试失败的承诺,我建议你看看 retry-as-promised 库
    • @Sae 示例已添加。
    【解决方案2】:

    最后我在做这个,发现有新版本的包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 它正在工作。

    我的问题已经解决了,但承诺我仍然需要学习,

    感谢您的所有建议/关注。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多