1

I know it is the most frquently asked question in javascript regarding asynchronous behaviour of functions. Still I am not able to figure out a working solution for my use case. What I am trying to do is lookup the redis cache using a key. I am using the exists function to check the key is present or not. If present then i'll return from cache if not then i'll set the key and then make a db call using this key as a db param. It seems very simple but no matter what I do i'm unable to return the value from the cache or the DB. If I make these calls outside the exist function then it works as the resolver function(graphql resolver) is an async function. This resolver functions expects a return value. So here is the code by which i'm unable to retun the value in any scenario:-

empId: async(obj, params, ctx, resolverInfo) => {

    await client.exists(obj.empId, async function(err, reply) {
      if (reply == 1) {

        return await getAsync(obj.empId).then(res => {
          console.log(res);
          return res;

        })
      } else {
        return await db.one('SELECT * FROM iuidtest WHERE empid = $1', [obj.empId])
          .then(iuidtest => {
            console.log(iuidtest.empid);
            return iuidtest.empid;
          })

      }
    });

    const doSomethingWith = empid => {

      console.log("empid = ", empid);

    }

I am getting the correct values in console but am unable to return. However if I directly make these calls in my resolver function i.e. outside of the redis exists function I am able to return the value.

empId: async(obj, params, ctx, resolverInfo) => {
    return await getAsync(obj.empId).then(res => {
          console.log(res);
          return res;

This way I am able to return the value from the resolver function. It would be really of great help if anybody can provide the working code for this instead of other links regarding how to return from async function using callbacks and promises. Here is another post reg the same. :- Redis async library does not have function that are in redis library for node.js Thanks in advance!

4
  • 1
    await clients.exists() will only work if that function returns a promise. According to your code it expects a callback function though, which means it doesn't return a promise and your code doesn't await anything. You need to promisify the client.exists() call. Commented May 25, 2020 at 12:29
  • "anybody can provide the working code for this" Welcome to Stack Overflow. Please note that this is not a free-coding service. Also, could you please explain which part you are not able to understand in this, so that others help you. Commented May 25, 2020 at 12:29
  • @Zukerberg Ok sorry I quoted that incorrectly. I am actually stuck in the part where and how to use promises with my exists function so that anyhow i am able to return the response from it. Commented May 25, 2020 at 13:11
  • @ Chris G I tried promisifying the exists function but was not able to return the response. I also don't understand why this can be returned outside the exist function but not inside the callback function of it? Commented May 25, 2020 at 13:13

1 Answer 1

2

If client.exists returns promise, the same code can be written as below:

empId: async (obj, params, ctx, resolverInfo) => {

    const exists = await client.exists(obj.empId);

    if (exists === 1) {
      return getAsync(obj.empId);
    }

    return await db.one('SELECT * FROM iuidtest WHERE empid = $1', [obj.empId])
      .then(iuidtest => {
        return iuidtest.empid;
      });

  }

If client.exists only accepts callback, then the code can be written as:

empId: async (obj, params, ctx, resolverInfo) => {

    async function empIdExists(empId) {

      return new Promise(function resolver(resolve, reject) {

        client.exists(obj.empId, function(err, reply) {

          if (err) {
            reject(err);
            return;
          }

          if (reply == 1) {
            resolve(1);
            return;
          } else {
            resolve(0);
            return;

          }

        })

      });

    }

    const exists = await empIdExists(obj.empId);

    if (exists === 1) {
      return getAsync(obj.empId);
    }

    return await db.one('SELECT * FROM iuidtest WHERE empid = $1', [obj.empId])
      .then(iuidtest => {
        return iuidtest.empid;
      });

  }

In the second version, notice that I have wrapped the client.exists call into an async function & called using await keyword.

Sign up to request clarification or add additional context in comments.

3 Comments

This is exactly what i was looking for! Thanks a lot. When trying to promisify I was not wrapping the call into the async function and then doing the call using await for that async function. This is why the same redis and db lookups where returning in the resolver as it was async i suppose? Though i'm still far from clear about async functions and use of promises. Would be very helpful if you can suggest where to start if one is a novice.
It is simple to understand. async functions are internally promise functions. async/await is syntatic sugar for using Promise constructor. If a function returns promise, it can be called using await keyword. If a function is an async function, ie: if there is async keyword prefixed, then you can do .then(...) on that function call. So, if you know that a function returns a promise, feel free to put await keyword when calling that function. There is nothing more to learn in there.
I would suggest you to write few simple promise functions & async functions and call them in both promise & async/await way to understand the dynamics.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.