node.js - 将 promiseAll 转换为渐进式 promise 解决(例如每 3 个promises)不起作用
问题描述
我有一个承诺列表,目前我正在使用 promiseAll 来解决它们
这是我现在的代码:
const pageFutures = myQuery.pages.map(async (pageNumber: number) => {
const urlObject: any = await this._service.getResultURL(searchRecord.details.id, authorization, pageNumber);
if (!urlObject.url) {
// throw error
}
const data = await rp.get({
gzip: true,
headers: {
"Accept-Encoding": "gzip,deflate",
},
json: true,
uri: `${urlObject.url}`,
})
const objects = data.objects.filter((object: any) => object.type === "observed-data" && object.created);
return new Promise((resolve, reject) => {
this._resultsDatastore.bulkInsert(
databaseName,
objects
).then(succ => {
resolve(succ)
}, err => {
reject(err)
})
})
})
const all: any = await Promise.all(pageFutures).catch(e => {
console.log(e)
})
因此,正如您在这里看到的,我使用 promise all 并且它有效:
const all: any = await Promise.all(pageFutures).catch(e => {
console.log(e)
})
但是我注意到它会影响数据库性能,所以我决定一次解决每 3 个问题。为此,我正在考虑不同的方法,例如 cwait、异步池或编写我自己的迭代器,但我对如何做到这一点感到困惑?
例如,当我使用 cwait 时:
let promiseQueue = new TaskQueue(Promise,3);
const all=new Promise.map(pageFutures, promiseQueue.wrap(()=>{}));
我不知道要在包装内传递什么,所以我现在通过 ()=>{} 加上我得到
Property 'map' does not exist on type 'PromiseConstructor'.
因此,无论我如何让它工作(我自己的迭代器或任何库),只要我对它有很好的理解,我都可以接受。如果有人能阐明这一点并帮助我摆脱这种困惑,我将不胜感激?
解决方案
首先,您问了一个关于失败的解决方案尝试的问题。这就是所谓的X/Y 问题。
所以事实上,据我了解你的问题,你想延迟一些数据库请求。
您不想延迟解决由Promise
数据库请求创建的...就像不!不要这样尝试!当数据库返回结果时,承诺将得到解决。干扰该过程是个坏主意。
我用你尝试的图书馆撞了一会儿......但我无法解决你的问题。所以我想到了循环数据并设置一些超时的想法。
我在这里做了一个可运行的演示:Delaying DB request in small batch
这是代码。请注意,我模拟了一些数据和数据库请求。你将不得不适应它。您还必须调整超时延迟。一整秒肯定太长了。
// That part is to simulate some data you would like to save.
// Let's make it a random amount for fun.
let howMuch = Math.ceil(Math.random()*20)
// A fake data array...
let someData = []
for(let i=0; i<howMuch; i++){
someData.push("Data #"+i)
}
console.log("Some feak data")
console.log(someData)
console.log("")
// So we have some data that look real. (lol)
// We want to save it by small group
// And that is to simulate your DB request.
let saveToDB = (data, dataIterator) => {
console.log("Requesting DB...")
return new Promise(function(resolve, reject) {
resolve("Request #"+dataIterator+" complete.");
})
}
// Ok, we have everything. Let's proceed!
let batchSize = 3 // The amount of request to do at once.
let delay = 1000 // The delay between each batch.
// Loop through all the data you have.
for(let i=0;i<someData.length;i++){
if(i%batchSize == 0){
console.log("Splitting in batch...")
// Process a batch on one timeout.
let timeout = setTimeout(() => {
// An empty line to clarify the console.
console.log("")
// Grouping the request by the "batchSize" or less if we're almost done.
for(let j=0;j<batchSize;j++){
// If there still is data to process.
if(i+j < someData.length){
// Your real database request goes here.
saveToDB(someData[i+j], i+j).then(result=>{
console.log(result)
// Do something with the result.
// ...
})
} // END if there is still data.
} // END sending requests for that batch.
},delay*i) // Timeout delay.
} // END splitting in batch.
} // END for each data.
推荐阅读
- unit-testing - Flutter、flutter_localization 和测试(如果我尝试模拟本地化,则只通过一项测试)
- php - 如何使用一些具有额外功能的驱动程序构建 laravel 包
- latex - 重新定义环境问题
- c++ - main.cppy9.cpp:(.text+0x4b): undefined reference to `add(int, int)'
- java - 如何将 JLabel 旋转到直立位置
- sql-server - 表中同时插入的记录可以重叠吗?
- python - 1048, "列 'user_id' 不能为空"
- javascript - 未捕获的错误:不允许 https://127.0.0.1:9002 覆盖此店面。在 webApplicationInjector.js:4
- javascript - Chart.js 在传递动态标签时不显示数据
- android - 自 Android Studio 3.6 以来,apk 大小和 zip 对齐方式发生了什么变化?