我有一个包含promises数组的数组,每个内部数组可以有4k,2k或500个promise。
总共有大约60k的承诺,我也可以用其他值来测试它。
现在我需要执行.Block(
System.Int32 $propertyValue,
System.Object[] $array,
System.Int32 $length,
System.Int32 $index,
System.Boolean $result) {
$propertyValue = $x.Bar;
$array = .Call .Constant<System.Collections.Generic.List`1[System.Object]>(System.Collections.Generic.List`1[System.Object]).ToArray();
$length = $array.Length;
$index = 0;
$result = False;
.Loop {
.If ($index < $length) {
.Block() {
.If ($propertyValue == (System.Int32)$array[$index]) {
.Block() {
$result = True;
.Break endLoop { }
}
} .Else {
.Default(System.Void)
};
$index++
}
} .Else {
.Break endLoop { }
}
}
.LabelTarget endLoop:;
$result
}
。
完成第一个内部数组后,我需要执行下一个Promise.all(BigArray[0])
,依此类推等等。
如果我尝试执行Promise.all(BigArray[1])
投掷:
致命错误call_and_retry_2分配失败 - 处理内存不足
我需要将每个promises串行执行,而不是并行执行,我认为这就是Node所做的。 我不应该使用新的库,但我愿意考虑答案!。
编辑:
以下是一段代码示例:
Promise.all(BigArray)
答案 0 :(得分:1)
Promise.all()
将检查作为 parallel 中的参数传递的每个promise结果,并在第一个错误时拒绝,或在完成所有promise后解析。
来自MDN:
Promise.all传递来自传递的可迭代对象中所有promise的值数组。值数组维护原始可迭代对象的顺序,而不是promises被解析的顺序。如果在可迭代数组中传递的东西不是promise,则由Promise.resolve转换为1。如果任何传入的承诺拒绝,所有承诺立即拒绝拒绝的承诺的价值,放弃所有其他承诺,无论他们是否已经解决。如果传递了一个空数组,则此方法立即解析。
如果您需要系列执行所有承诺,那么Promise.all()
方法将 用于您的应用。相反,您需要找到一种解决您的承诺的迭代方法。这将很困难; node.js本质上是异步的,并且使用循环(根据我的知识和经验),在循环中从promise中收到响应之前不会阻塞。
修改强>
存在一个名为promise-series-node的库,我认为这可能会对你有所帮助。由于您已经创建了承诺,因此您可以将其传递给BigArray
:
promiseSeries(BigArray).then( (results) => {
console.log(results);
});
在我个人看来,你从60k +承诺开始的方法不仅需要花费大量的时间,而且还需要系统执行它们的资源(这就是你内存不足的原因)。我认为您可能需要考虑更好的应用程序架构。
Edit2,承诺是什么?::
promise表示异步操作的结果,它可以采用以下三种状态之一:
一旦承诺履行或被拒绝,承诺就是不可改变的。你可以链接promises(非常适合避免重复的回调),以及嵌套它们(当关闭是一个问题时)。网上有很多很棒的文章,here is one I found to be informative。
答案 1 :(得分:1)
在ES2017中使用async / await非常简单:
(async () => {
for (let i = 0; i < BigArray.length; i++) {
await Promise.all(BigArray(i));
}
})();
答案 2 :(得分:0)
promise库bluebird提供了一个名为Promise.map的辅助方法,它将数组或数组的promise作为其第一个参数,并将其所有元素映射到结果数组,而结果数组又得到了保证。也许你可以尝试这样的事情:
UPDATE [Items]
SET [IsInSeason] = 1
WHERE [Name] like '%summer%'
但如前所述,这仍然是一项非常耗费资源的任务,可能会占用所有可用内存。
答案 3 :(得分:0)
这里的答案很好Callback after all asynchronous forEach callbacks are completed
function asyncFunction (item, cb) {
setTimeout(() => {
console.log('done with', item);
cb(item*10);
}, 1000*item);
}
let requests = [1,2,3].map((item) => {
return new Promise((resolve) => {
asyncFunction(item, resolve);
});
})
Promise.all(requests).then(
// () => console.log('done')
function(arr){
console.log(arr)
console.log('done')
}
);
答案 4 :(得分:0)
Promise.all
无法使用,您可以使用Array.reduce
逐个处理BigArray
元素:
BigArray.reduce((promiseChain, currentArray) => {
return promiseChain.then(chainResults =>
Promise.all(currentArray).then(currentResult =>
[...chainResults, currentResult]
)
);
}, Promise.resolve([])).then(arrayOfArraysOfResults => {
// Do something with all results
});