【发布时间】:2020-05-15 06:22:15
【问题描述】:
我正在尝试在循环中等待多个承诺。此循环必须转 3 次发送 3 个产品数组。两个初始循环将分别发送 1000 个产品,第三个循环将发送 500 个。
事实是该函数忽略了第三轮而不是将其发送到数据库,正如您在该日志中看到的那样,仅添加了 2000 个产品
我的方法
const MAXIMUM_POST_SIZE = 1000
export const addProducts = (products) => new Promise(
(resolve, reject) => {
for (let i = 0; i < Math.ceil(products.length / MAXIMUM_POST_SIZE); i += 1) {
const indexToStartExtraction = i * MAXIMUM_POST_SIZE;
const sizeOfExtraction = indexToStartExtraction + MAXIMUM_POST_SIZE;
const extractedProducts = products.slice(indexToStartExtraction, sizeOfExtraction);
const ref = firebase.ref('products');
const normalizedPostData = arrayToJsonObjectWithUid({ products: extractedProducts, ref });
console.log(extractedProducts.length);
ref.update(normalizedPostData).then(() => {
console.log(`Doing ${i} call`);
resolve(true);
})
.catch((err) => reject(err));
}
},
);
我试过没有成功:
export const addProducts = (products) => new Promise(
(resolve, reject) => {
const promises = [];
for (let i = 0; i < Math.ceil(products.length / MAXIMUM_POST_SIZE); i += 1) {
const indexToStartExtraction = i * MAXIMUM_POST_SIZE;
const sizeOfExtraction = indexToStartExtraction + MAXIMUM_POST_SIZE;
const extractedProducts = products.slice(indexToStartExtraction, sizeOfExtraction);
const ref = firebase.ref('products');
const normalizedPostData = arrayToJsonObjectWithUid({ products: extractedProducts, ref });
console.log(extractedProducts.length);
promises.push(ref.update(normalizedPostData));
}
Promise.all(promises)
.then(() => resolve())
.catch(() => reject());
},
);
如何正确等待每个承诺?
【问题讨论】:
-
基本上,您不能在同步函数的循环中等待,但您可以将执行 API 调用的 Promise 和在特定时间后解析的 Promise 链接起来,并拥有一个异步函数来执行您的操作想要。
-
这与您的问题无关,但我建议您将数组分块,而不是您在这里执行 for 循环的方式。 lodash has a chunk function。这是做什么的,如果你给它一个
[1,2,3,4,5,6,7]的数组,并告诉它把它分成3个,它会给你[[1,2,3],[4,5,6],[7]],然后你可以遍历分块的数组,将你的元素分组到数组中大小合适。 -
在 Stack Overflow 上,请不要显示文字图片。将文本复制到问题本身,以便于阅读和搜索。
-
"...不违反 eslint 的规则..."
no-await-in-loops不是“推荐”规则之一,从rule list 可以看出。如果您阅读rule documentation,它特别指出它试图保护您免受无意以串行方式而不是并行方式进行操作。由于您想按顺序进行操作(据我了解这个问题),因此该规则不适用。如果您有一个不寻常的规则集启用它,请使用代码注释为此代码禁用它。 -
为了清楚起见:您是要并行运行这些更新(全部同时运行)还是串行运行(一个接一个地运行)?如果您希望它们并行运行,您现有的带有
Promise.all的代码应该可以正常工作。当然,您必须等待addProducts的承诺解决。
标签: javascript firebase promise