Leonardo Alves
Leonardo Alves

Reputation: 1946

Bluebird promise loop

I am trying to get all records from a DynamoDB table using promises. The problem is that DynamoDB do not return all items in one call I have to make multiple calls. If LastEvaluatedKey is not null means that I need to make another call with that key to get the remaining records. In my code I am checking that and resolving only after LastEvaluatedKey is null. But the console.log("done") is not being executed.

Here is my code:

function query(params) {
    return new Promise(function(resolve, reject) {
        docClient.query(params, function(err, data) {
            if (err) {
                reject(err)
            } else {
                resolve(data);
            }
        });    
    })
}

function getAllRecords(params, combinedData) {
   return new Promise(function(resolve, reject) {
        query(params)
       .then(function(data) {
           if(!combinedData) {
               combinedData = [];
           }
           combinedData.push(data.Items); 
           if(data.LastEvaluatedKey) {
                params.ExclusiveStartKey = data.LastEvaluatedKey;
                getAllRecords(params, combinedData)
            }
            else {
                resolve(combinedData);
            }
       })    
   })


}

getAllRecords(params)
.then(function() {
  console.log('done')
})
.catch(function(error) {
    console.log(error);
})

It's probably a misconception on how promises work from my part. If someone can give me an idea how to make this work. That would be great.

Upvotes: 1

Views: 169

Answers (1)

JLRishe
JLRishe

Reputation: 101662

You've fallen prey to the explicit promise construction antipattern, in which you are manually constructing promises when you don't need to.

Generally the only time you need to use the Promise constructor is when you are converting non-Promise async code to Promise async code. You've already done that in your query() function, so you don't need to use the Promise constructor in your getAllRecords() function.

You should do this instead:

function getAllRecords(params) {
    return query(params).then(function (data) {
        var items = [data.Items];

        if(data.LastEvaluatedKey) {
            params.ExclusiveStartKey = data.LastEvaluatedKey;

            return getAllRecords(params).then(function (theRest) {
                return items.concat(theRest);
            });
        }

        return items;
    });
}

Upvotes: 1

Related Questions