简体   繁体   中英

How promises are resolved?

I have a script which executes a lot of promises. Basically my script, "Task", starts when a new record is added to the database. Based on this record I make a request to an API and get an array of results. I then save those results to the database. Then I use the same array of results to make a request per result to another api used to get images. Then all those images will be uploaded to S3.

So, for each task I execute, I trigger a lot of requests, queries to database, updates, etc. All of those are resolved in promises. So my question is, what's will happen if I insert many "Task" records into the database? What's the order for promise execution? Will the program wait until the first task (and sub-tasks) end? Or will the program throw results independently by task while other tasks are resolving too?

This is because I can't wait until all promises of first task have been resolved to start to execute the next task.

If you have some additional questions, just tell me, I can update the question.

Here is an implementation of your Task, onRecordAddTask . that clarifies the order for promise execution.

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 should be called with each newly inserted record into your database. The task requests an API requestAPI with your record, and returns an array of results . Then, for each result of results we saveToDatabase while we getImages per result in parallel; we wait for images per result as arraysOfImages . Finally, we upload all images to s3 as uploadToS3 .

I should mention that I wrote a library to handle complex async tasks such as yours; here is how you would simplify the above code with that library.

const { pipe, fork, map, get } = require('rubico')

const onRecordAddTask = pipe([
  requestAPI,
  fork([
    map(getImages),
    map(saveToDatabase),
  ]),
  get(0),
  map(map(uploadToS3)),
])

I can't wait until all promises of first task are been resolved to start to execute the latest task.

because onRecordAddTask returns a single promise, you are free to let it run away so that it does not block you from executing the latest task.

what will happen if I insert many "Task" records on database

you will start off many executions of the task onRecordAddTask

The short answer is: Yes

You can run all promises at the same time.

Use Promise.all([]) and pass in an array of promises.

Your code will look like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM