Javascript 使用异步函数在setTimeout和for循环中插入许多
我正在尝试编写以下代码并使其同步工作,但唯一的问题是它在Javascript 使用异步函数在setTimeout和for循环中插入许多,javascript,node.js,mongodb,asynchronous,mongoose,Javascript,Node.js,Mongodb,Asynchronous,Mongoose,我正在尝试编写以下代码并使其同步工作,但唯一的问题是它在console.log中正常工作,它会在1秒内延迟打印数组中的每个项目,但无法使用以下结构: for (let i = 0; i < array.length; i++) { setTimeout(function () { 1.http request via rp or request.get (I receive a huge data array) 2. .map results
console.log
中正常工作,它会在1秒内延迟打印数组中的每个项目,但无法使用以下结构:
for (let i = 0; i < array.length; i++) {
setTimeout(function () {
1.http request via rp or request.get (I receive a huge data array)
2. .map results
3.insert to Mongo via mongoose
}
}
或者我的版本与rp
几乎相同,而不是request.get
默认情况下,我有mongoose.Promise=global.Promise代码>
为什么这会引起问题?因为body.length
是一个非常庞大的数据集,占用了大量内存。(现在想象20多个阵列,其中插入了insertMany
)
所以Mongo试图一次插入许多请求的所有响应(当它们准备好时,没有1000秒的延迟)。实际上,这就是为什么我选择了request
而不是rp
(request-promise
),但它看起来也是异步的。因此,我应该从npm
中选择另一个httpget模块并切换到它。不用担心吗
或者我应该将这个操作包装成承诺| |生成一个异步函数,并在每次正确完成时(例如1000秒)在循环内调用它。在这种情况下,我在StackOverflow上发现的唯一实际情况是:
有点过时了。有什么想法吗?好吧,我没有你的实际代码,所以我将用伪代码编写你能做的
const chunkArray = (array, chunkSize) => {
let i,j,chunks = [];
for (i = 0, j = array.length; i < j; i += chunkSize) {
chunks.push(array.slice(i, i + chunkSize));
}
return chunks;
}
for (let i = 0; i < array.length; i++) {
let bigArray = await request('your data url');
// do some mapping or whatever
// then break your large array into smaller chunks
let chunks = chunkArray(bigArray, 10);
let j;
for (j = 0; j < chunks.length; j++) {
await collection.insertMany(chunks[j]);
}
}
const chunkArray=(数组,chunkSize)=>{
设i,j,chunks=[];
对于(i=0,j=array.length;i
解决我的问题的实际代码是:
async function test (name, url, lastModified) {
try {
const response = await rp({uri: url, json: true});
response.map(async (element) => {
if (element.buyout > 0) {
element.price = (element.buyout / element.quantity);
}
element.lastModified = lastModified
});
return collection.insertMany(response);
} catch (err) {
console.error(err)
}
}
async function addAsync() {
const z = await test();
console.log(z);
}
addAsync();
如果不想一次插入所有响应,那么不要使用insertMany。循环响应并逐个插入。实际上我不确定。创建50000+个元素比使用.insertMany(array)
更好。我对request
的回复并不是一个简单的文档,而是包含大量文档的数组。[TL:DR:我需要一个接一个地插入10+个数组(body
),而不是一次全部插入。这就是为什么我使用for
和setTimeout
在这种情况下,逻辑很简单:通过url数据集body
请求(它是一个数组)然后将它插入Mongo,因为如果我一次插入所有的内存,它需要大量的RAM(如我前面提到的)]如果您想按顺序执行,请在循环中使用wait
,而不是map
async function test (name, url, lastModified) {
try {
const response = await rp({uri: url, json: true});
response.map(async (element) => {
if (element.buyout > 0) {
element.price = (element.buyout / element.quantity);
}
element.lastModified = lastModified
});
return collection.insertMany(response);
} catch (err) {
console.error(err)
}
}
async function addAsync() {
const z = await test();
console.log(z);
}
addAsync();