admin管理员组

文章数量:1405379

I've created a very short/simple example of a problem I'm having with Promises in a script utilizing the aws-sdk package for Node.js.

In short, the script is not waiting at the await keyword. It loops through the loop without waiting for the async function to successfully plete before moving on.

Code example:


main.js

const AWS = require('aws-sdk')
import constants from '@/constants'

AWS.config.update({
  accessKeyId: constants.awsAccessKey,
  secretAccessKey: constants.awsSecretAccessKey,
  region: constants.awsRegion
})

export const s3 = new AWS.S3({apiVersion: '2006-03-01'})

click some button and trigger testS3() method...


testActions.js

import { s3 } from '@/main.js'

export async function testS3 () {
  const testParams = {
    Bucket: AWS_BUCKET,
    Key: `test_file.txt`,
    Body: 'Testing stuff'
  }

  async function testFunction(layer) {
    console.log('in prepare design 1')
    const result = await s3.putObject(testParams).promise()
    console.log(`the results: ${result}`)
  }

  [1,2,3].forEach(async (x) => {
    const result = await testFunction()
  })
}

Output from the debugger:


I was expecting the messages to be interleaved, which is what makes sense if you follow the flow of the logic.

It should be in prepare design 1, and then display the results..., then go through and do that 2 more times.

The output displaying in prepare design 1 three times right off the bat shows me that the loop is not waiting for the function before continuing.


Have I setup async/await wrong in some way? I've tried multiple different iterations and can't seem to get this working how I'm expecting it to.

I've created a very short/simple example of a problem I'm having with Promises in a script utilizing the aws-sdk package for Node.js.

In short, the script is not waiting at the await keyword. It loops through the loop without waiting for the async function to successfully plete before moving on.

Code example:


main.js

const AWS = require('aws-sdk')
import constants from '@/constants'

AWS.config.update({
  accessKeyId: constants.awsAccessKey,
  secretAccessKey: constants.awsSecretAccessKey,
  region: constants.awsRegion
})

export const s3 = new AWS.S3({apiVersion: '2006-03-01'})

click some button and trigger testS3() method...


testActions.js

import { s3 } from '@/main.js'

export async function testS3 () {
  const testParams = {
    Bucket: AWS_BUCKET,
    Key: `test_file.txt`,
    Body: 'Testing stuff'
  }

  async function testFunction(layer) {
    console.log('in prepare design 1')
    const result = await s3.putObject(testParams).promise()
    console.log(`the results: ${result}`)
  }

  [1,2,3].forEach(async (x) => {
    const result = await testFunction()
  })
}

Output from the debugger:


I was expecting the messages to be interleaved, which is what makes sense if you follow the flow of the logic.

It should be in prepare design 1, and then display the results..., then go through and do that 2 more times.

The output displaying in prepare design 1 three times right off the bat shows me that the loop is not waiting for the function before continuing.


Have I setup async/await wrong in some way? I've tried multiple different iterations and can't seem to get this working how I'm expecting it to.

Share Improve this question asked Feb 12, 2019 at 6:27 qarthandsoqarthandso 2,1882 gold badges27 silver badges47 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

The displayed behavior is correct, because forEach's handler is also an async function:

  async (x) => {
    const result = await testFunction()
  }

So the forEach loop will run 3 async functions immediately. Each of those function will await for the rest of the promise chain asynchronously.

If you want a synchronous execution, use a normal for loop:

for(var i=0; i<3; i++){
  const result = await testFunction()
}

This an addition to AVAVT's answer (as I can't ment on it), you can also do so as such so you don't have to manually enter in the number of iterations and intending on using the iterating value.

import { s3 } from '@/main.js'

export async function testS3 () {
  const testParams = {
    Bucket: AWS_BUCKET,
    Key: `test_file.txt`,
    Body: 'Testing stuff'
  }

  async function testFunction(layer) {
    console.log('in prepare design 1')
    const result = await s3.putObject(testParams).promise()
    console.log(`the results: ${result}`)
  }

  for (const iterator of [1,2,3]) {
      const result = await testFunction();
  }

}

本文标签: javascriptAsyncawait Not working with AWS S3 Nodejs SDKStack Overflow