dds
dds

Reputation: 2415

Promises and condition from async call

I'm implementing my service using Node.js with AWS DynamoDB (aws-sdk).

It's unclear for me how to implement the following scenario with promises:

  1. I get a request to modify an entity with specified attributes
  2. I'm trying to find the entity in the DB (async call find)
  3. If the entity not found then create one with initial state (async call createInitialStateObject)
  4. Modify the entity (which was in the DB before or just created on step 3) according to specific rules (async call applyModifications)

This is my first attempt:

function scenario(params) {
    find(params).then((data) => {
        let objectExists = checkExistense(data);
        if (!objectExists) {
            createInitialStateObject(params).then((data) => {
                console.log("Object created");
                // OK
            }).catch((err) => {
                console.error("Object not created");
                // exit and return error
            });
        }
        applyModifications(params).then((data) => {
            // OK, return data
        }).catch((err) => {
            // exit and return error
        });
    }).catch((err) => {
        // exit and return error
    });
}

But the flaw here is that creation could happen before the modification, it's not bound to happen one after another.

The other attempt works, but looks a bit weird. I create an empty promise to call in case the object already exists:

function scenario(params) {
    find(params).then((data) => {
        let conditionalPromise = new Promise((resolve) => {
            resolve(null);
        });
        let objectExists = checkExistense(data);
        if (!objectExists) {
            conditionalPromise = createInitialStateObject(params);
        }
        conditionalPromise.then((data) => {
            applyModifications(params).then((data) => {
                // OK, return data
            }).catch((err) => {
                // exit and return error
            });
        }).catch((err) => {
            // exit and return error
        });
    }).catch((err) => {
        // exit and return error
    });
}

How it should be implemented in a right way?

Upvotes: 1

Views: 89

Answers (1)

Johannes Merz
Johannes Merz

Reputation: 3342

Creating 'empty' or sync. Promises isn't unusual. There is even a short way of doing that: Promise.resolve(value) creates and resolves a Promise immediately.

Besides that you should make use of proper chaining and stop nesting things so much. Once you are in a chain, you don't even need to resolve an empty promise as a return value of a non thenable object is interpreted as exactly this.

function scenario(params) {
  return find(params)
    .then(data => {
      let objectExists = checkExistense(data);
      if (!objectExists) {
        return createInitialStateObject(params);
      }
      // if we return nothing (or null in your case) this will be the same as return Promise.resolve()
      return null;
    })
    .then(data => applyModifications(params))
    .then(data => console.log(data))
    .catch(err => console.log(err));
        // exit and return error
}

Upvotes: 2

Related Questions