node.js - Promises 在定义时执行而不是 Promises.all?
问题描述
我正在尝试创建一组承诺,以便我可以批量承诺而不是一起执行它们以避免关闭我的服务器。我想一次执行最多 20 个承诺。我写了以下代码:
let promises = [];
let create;
let update;
let i=0;
let users = users.json;
if (users && usersjson.users.length) {
for (const user of users) {
if (userexists) {
update = new promise(async (resolve,reject) => {
//Function to update user
});
promises.push(update);
i++;
} else {
create = new promise (async (resolve,reject) => {
//Function to create a new user
});
promises.push(update);
i++;
}
if (promises.length >= 20 || i >= usersjson.users.length) {
await Promise.all(promises)
.then((response)=>{
console.log(response);
promises=[];
}).catch((err)=> {
console.log(err);
})
}
}
}
但是,我发现promise是在我定义它们时执行的,而不是在我调用Promise.all时被推入数组并执行,我不知道为什么。
我也希望 Promise.all 函数继续运行,即使单个承诺被拒绝,如果我的代码构建方式可行的话。如果代码失败,我在每个承诺中都有一个问题,这是正确的方法吗?
解决方案
正如评论中提到的,promise 对象实际上在您执行异步操作后立即进入“挂起”状态,并且在操作完成后立即“完成”。
因此,在您的代码中,您实际上为所有用户创建并运行异步操作,而不仅仅是其中的 20 个。
有两种解决方案适合您。主要的一个是创建返回一个 Promise 并且一次只运行 20 个的函数。
const jobs = users.map(user => () => user.update(...)); // array of functions
while (jobs.length > 0) {
await Promise.all(jobs.splice(0,20).map(job => job())); // take 20 and process
}
另一种解决方案是使用像bluebird这样的库,它有很多有用的方法来处理 Promise。您可能想要的一个是map()
支持并发限制。
你的第二个问题是关于Promise.all
导致整个系列失败的错误。为了防止您可以添加.catch()
到每个作业,例如,返回一个null
there 或任何其他值,这将帮助您确定某些操作失败。当然,这种方法也会防止Promise.all
中断。
const jobs = users.map(user => () => user.update().catch(e => null));
推荐阅读
- linq-to-sql - 为什么在实体框架查询上使用 ToDictionary 时会收到 NullReferenceException?
- visual-studio - Xamarin.Android.Crashlytics 2.9.4.1 - CrashlyticsCore 上的 NoClassDefFoundError
- scala - 使用 Scala Spark 从 URL 获取结果
- r - 应用正则表达式来比较 R 中不同长度的数据帧中的值
- php - RouteCollection.php 第 161 行中的 Laravel 项目 NotFoundHttpException:
- python - 在 Python 中限制访问的类似 Java 的接口
- php - 没有得到所需的日期
- typescript - 使用 typescript 编译器 API 获取接口字段类型信息
- mysql - 计算 MYSQL 中每个用户的子表中的不同记录
- r - 从结果与字符向量匹配的不同数据帧中调用信息