执行 Promise.all 时出错(关闭连接/挂断)
Error when do Promise.all (close connection / hang up)
我正在使用 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)
Is there any limitation for Promise.all
.?
或
Is there any better solution to export batch / bulk data to Google
Spreadsheet?
Promise.all
如果其中一个 promise 抛出,则将抛出。如果即使一个 promise 失败了你也想继续,你不想像上面的代码那样重新抛出它。
您可以将其重新添加到待定队列中,然后重试。
另外,我可以考虑批处理它。将它们分成块并上传。
示例:
创建一个工作池(工作数 = 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
最后我在做这个,发现有新版本的包 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 它正在工作。
我的问题已经解决了,但承诺我还需要学习,
感谢您的所有建议/关注。
我正在使用 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)
Is there any limitation for
Promise.all
.?
或
Is there any better solution to export batch / bulk data to Google Spreadsheet?
Promise.all
如果其中一个 promise 抛出,则将抛出。如果即使一个 promise 失败了你也想继续,你不想像上面的代码那样重新抛出它。
您可以将其重新添加到待定队列中,然后重试。
另外,我可以考虑批处理它。将它们分成块并上传。
示例:
创建一个工作池(工作数 = 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
最后我在做这个,发现有新版本的包 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 它正在工作。
我的问题已经解决了,但承诺我还需要学习,
感谢您的所有建议/关注。