如何兑现承诺?

时间:2020-05-20 18:29:45

标签: javascript node.js promise

我有一个执行很多承诺的脚本。基本上,当新记录添加到数据库时,我的脚本“任务”就会启动。根据此记录,我向API发出请求并获得结果数组。然后,我将这些结果保存到数据库中。然后,我使用相同的结果数组对每个结果向另一个用于获取图像的api发出请求。然后所有这些图像都将上传到S3。

因此,对于我执行的每个任务,我都会触发许多请求,对数据库的查询,更新等。所有这些都在promise中得到解决。所以我的问题是,如果我将许多“任务”记录插入数据库,将会发生什么?履行承诺的顺序是什么?程序会等到第一个任务(和子任务)结束吗?还是在其他任务也解决时,程序会按任务独立地抛出结果?

这是因为我迫不及待地解决了第一个任务的所有诺言,开始执行下一个任务。

如果您还有其他问题,请告诉我,我可以更新问题。

2 个答案:

答案 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')
}