Search code examples
javascriptnode.jslambdaamazon-dynamodbes6-promise

Returns Promise.all doesn't execute the provided promises


I'm currently facing an issue with returning Promise.all() from within a then() block.

const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

const NUMBER_OF_ITEMS_PER_BATCH = 25;

const createBatches = (items) => {
    // function that creates all the batches
}

function getPromisesArray (items) {
    let batches = createBatches(items);
    let promiseArr = [];
    for(batch of batches) {
        categoriesProductsBatchWriteParams.RequestItems[categoriesProductsTable] = batch;
        promiseArr.push(dynamodb.batchWriteItem(categoriesProductsBatchWriteParams).promise)
    }
    return promiseArr;
}

// deleting an item from the first table
dynamodb.deleteItem(shopsCategoriesParams).promise()
// deleting an item from the second table
.then(() => dynamodb.deleteItem(categoriesTableParams).promise())
//querying the third table to get all the items that have a certain category id
.then(() => dynamodb.query(categoriesProductsQueryParams).promise())
.then(result => {
    if(result.Count > NUMBER_OF_ITEMS_PER_BATCH) {
        // deleting all those items with batchWrite
        return Promise.all(getPromisesArray(result.Items));
    } else {
        categoriesProductsBatchWriteParams.RequestItems[categoriesProductsTable] = buildArrayForBatchWriteDelete(result.Items);
        return dynamodb.batchWriteItem(categoriesProductsBatchWriteParams).promise()
    }
})
.then(result => {
    // this console logs [[Function: promise]]
    console.log(result);
    callback(null, 'categories were deleted successfully')
})
.catch(err => {
    console.log(err);
    callback(`Error: ${err}`);
})

I currently have three different tables in dynamoDB and I have to delete items from those tables sequentially. One table stores the relationship between categories and shops, one stores the categories, and finally, the third table stores the relationship between categories and products. So, this function's aim is to delete a category. Therefore I have to delete the relationship in the Shops_Categories_Table (one-to-one), after which I'm deleting the category in the Categories Table, and finally I'm deleting the relationship between categories and products (one-to-many) in the third table. I'm querying Cateogries_Products_Table using the categoryId partition key to retrieve all products related to that category. Finally, I delete all the products using the dynamodb batchwriteItem method.

So issue here is the following, the batchwriteItem can only delete a max of 25 items at a time, which is why I'm creating batches holding each 25 items. This is done with the createBatches function which works as intended. I then create an array which stores a number of dynamodb.batchwrite(params).promise promises. I pass this array of promises to the Promise.all() method and return it from within the then block. But somehow the promises don't get executed and instead it returns and then console logs [[Function: promise]]. I tried using my own custom Promise, stored it in an array, and passed that one to Promise.all() which worked fine. For whatever reason though those dynamodb promises don't get executed.


Solution

  • It appears that you were creating an array of methods, not an array of promises because you're pushing .promise into the array instead of .promise().

    Change this:

    promiseArr.push(dynamodb.batchWriteItem(categoriesProductsBatchWriteParams).promise)

    to this:

    promiseArr.push(dynamodb.batchWriteItem(categoriesProductsBatchWriteParams).promise())


    FYI, promises don't execute so that isn't really the right phrasing to use in your description and title. A promise is merely a tool for monitoring an asynchronous operation that has already been executed or initiated by other code.