How to return from nested function in Node.js?

痴心易碎 提交于 2021-01-29 06:09:06

问题


I'm wrapping my dynamoDB function into another function and I'm having issues with returning it to the "item" const. What I'm missing here?

Works:

    const params = {
      TableName: table,
      Key: {
        id: id
      },
    };

    dynamoDb.get(params, (error, result) => {
      if (error) {
        console.error(error);
        callback(null, {
          statusCode: error.statusCode || 501,
          body: 'Couldn\'t fetch the item.',
        });
        return;
      }

      const item = result.Item
    })

Doesn't work (returns undefinied):

  const getFromDb = () => {
    const params = {
      TableName: table,
      Key: {
        id: id
      },
    };

    dynamoDb.get(params, (error, result) => {
      if (error) {
        console.error(error);
        callback(null, {
          statusCode: error.statusCode || 501,
          body: 'Couldn\'t fetch the item.',
        });
        return;
      }

      return result.Item
    })
  }

  // Get from db
  const item = getFromDb()
  // do stuff with result item...

回答1:


What currently happens in your code is getFromDb function will run dynamoDb.get(...) and immediately return (undefined in your case, because there is no return statement inside getFromDb). By the time getFromDb returns, your dynamoDb request hasn't even resolved yet, it will resolve at some point in the future and call the callback you provided (error, result) => { ... }

To achieve what you described, you need to:

  1. make getFromDb return Promise which will only resolve after your request resolves
  2. await for that function when calling it, getting result into which your Promise resolves (or and error if it rejects)

.

// marking this function async is not required but good to have
// to not forget that this function returns a promise, not immediate result
const getFromDb = async () => {
  // wrapped body in a promise
  return new Promise((resolve, reject) => {
    const params = {
      TableName: table,
      Key: {
        id: id
      },
    }

    dynamoDb.get(params, (error, result) => {
      if (error) {
        // in case of error, we reject promise with that error
        reject(error)
        return
      }
      // otherwise, we resolve with result
      resolve(result.Item)
    })
  })
}

// usage with async/await
// I wrapped significant code in asynchronous function f and then called it
// just to emphasize that you can only use async/await inside async function
// if you are already in async function, you don't need to do this
const f = async () => {
  try {
    const item = await getFromDb();
    console.log(item)
  } catch(error) {
    // the error we rejected with
    console.error(error)
  }
}

f()


// alternative way without async/await, using Promise chaining
getFromDb()
  .then(item => console.log(item))
  .catch(error => console.error(error))


来源:https://stackoverflow.com/questions/58569495/how-to-return-from-nested-function-in-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!