我有一个执行很多承诺的脚本。基本上,当新记录添加到数据库时,我的脚本“任务”就会启动。根据此记录,我向API发出请求并获得结果数组。然后,我将这些结果保存到数据库中。然后,我使用相同的结果数组对每个结果向另一个用于获取图像的api发出请求。然后所有这些图像都将上传到S3。
因此,对于我执行的每个任务,我都会触发许多请求,对数据库的查询,更新等。所有这些都在promise中得到解决。所以我的问题是,如果我将许多“任务”记录插入数据库,将会发生什么?履行承诺的顺序是什么?程序会等到第一个任务(和子任务)结束吗?还是在其他任务也解决时,程序会按任务独立地抛出结果?
这是因为我迫不及待地解决了第一个任务的所有诺言,开始执行下一个任务。
如果您还有其他问题,请告诉我,我可以更新问题。
答案 0 :(得分:1)
这是您的任务onRecordAddTask
的实现。明确了承诺执行的顺序。
const requestAPI = record => {/* make API request */}
const saveToDatabase = result => {/* save result to database */}
const getImages = apiResult => {/* make images API request */}
const flatten = arr => arr.flat(1)
const uploadToS3 = image => {/* upload to s3 code */}
const onRecordAddTask = async record => {
const results = await requestAPI(record)
const [arraysOfImages,] = await Promise.all([
await Promise.all(results.map(getImages)),
await Promise.all(results.map(saveToDatabase)),
])
await Promise.all(flatten(arraysOfImages).map(uploadToS3))
}
onRecordAddTask
应该与每个新插入的记录一起调用到数据库中。该任务将使用您的记录请求一个API requestAPI
,并返回一个results
数组。然后,对于每个结果,我们saveToDatabase
并行,而我们getImages
每个结果并行;我们等待每个结果的图像为arraysOfImages
。最后,我们将所有图像作为uploadToS3
上载到s3。
我应该提到我写了一个库来处理复杂的异步任务,例如您的;这是使用该库简化上述代码的方法。
const { pipe, fork, map, get } = require('rubico')
const onRecordAddTask = pipe([
requestAPI,
fork([
map(getImages),
map(saveToDatabase),
]),
get(0),
map(map(uploadToS3)),
])
我迫不及待地解决了第一个任务的所有诺言,开始执行最新任务。
由于onRecordAddTask
返回一个诺言,您可以放任它走开,以便它不会阻止您执行最新任务。
如果我在数据库中插入许多“任务”记录,会发生什么情况
您将开始执行任务onRecordAddTask
答案 1 :(得分:-2)
简单的答案是:是
您可以同时履行所有诺言。
使用Promise.all([])
并传递一组诺言。
您的代码将如下所示:
async function main() {
const promises = []
for(const task of tasks){
promises.push(task)
}
console.log('All promise at once')
await Promise.all(promises)
console.log('All promise at once done')
}