0

I'm very new to javascript in general and I'm doing a school project that builds a simple lambda function to save some data to DynamoDB from an HTTP request.

First, I had this version:

exports.handler = async (event) => {
    var params = {
        TableName: 'graph',
        ReturnConsumedCapacity: "TOTAL",
        Item: null
    };
    for (let input of event.inputs) {

        params.Item = {
            'key' : input.key,
            'value' : input.value
        };
        await DynamoDB.DocumentClient.put(params, function(err, data) {
            if (err) {
                console.log("Error", err);
            } else {
                console.log("Success", data);
            }
        });
    }
};

To my shallow understanding, an async function like the handler should wait for any await statement to finish executing, but I got nothing in the database. But even for some reasons if the lambda function execution didn't wait for DynamoDB.DocumentClient.put() to finish, wouldn't the DynamoDB.DocumentClient.put() finish on its own after the lambda has returned?

Then I followed some other people's examples and added promise() to the end:

exports.handler = async (event) => {
    var params = {
        TableName: 'graph',
        ReturnConsumedCapacity: "TOTAL",
        Item: null
    };
    for (let input of event.inputs) {

        params.Item = {
            'key' : input.key,
            'value' : input.value
        };
        await DynamoDB.DocumentClient.put(params, function(err, data) {
            if (err) {
                console.log("Error", err);
            } else {
                console.log("Success", data);
            }
        }).promise();
    }
};

Now even though it successfully put data into the database, the log shows 6 'Success' messages where I only put 3 pairs of key-value pairs. After some playing around, I realize the 'Success' messages appear once in the first callback, twice in the second, and three times in the third. I have no clues when it behaves like this at all. Can someone shed some light on this, please? Thank you

ydylwj23
  • 3
  • 2
  • There is no example mixing `DocumentClient.put` callback style with `promise()`. https://stackoverflow.com/questions/51328292/how-to-use-async-and-await-with-aws-sdk-javascript/51328537#51328537 – hoangdv Feb 21 '21 at 12:04

1 Answers1

1

You're mixing callbacks and promises. Callbacks were the preferred way to deal with async code (and still is preferred by some i guess), until promises were introduced. It's not recommended to mix these two for the same purpose.

This would be more correct as you're using the built-in 'then' method of the Promise class:

    await DynamoDB.DocumentClient.put(params)
          .promise()
          .then((data) => {
             console.log(data);
           })
          .catch((err) => {
             console.log(err);
           });

It doesn't break anything using the callback as well though. Here is a really good answer that explains promises:

Aren't promises just callbacks?

When it comes to it logging 6 times, that doesn't make any sense if the array passed to the loop only has 3 items. If you could provide the output in your original post, I'll see if i can make sense of it and give you an updated answer.

Koronag
  • 157
  • 1
  • 15
  • After some playing around, I realize the number of success logs I got between separators is different. ``` console.log("separator"); await DynamoDB.DocumentClient.put(params, function(err, data) { if (err) { console.log("Error", err); } else { console.log("Success", data); } }).promise(); ``` The output: ``` separator Success // sometimes 2 success here separator Success Success // sometimes only 1 success here separator Success Success // sometimes only 1 success here ``` – ydylwj23 Feb 21 '21 at 23:27