为什么当被调用函数返回一个对象时,我的调用函数会收到未定义的值?

时间:2019-04-05 21:39:09

标签: node.js

下面的getProductById函数调用fetchProductFromCache函数。产品被获取并记录到fetchProductFromCache函数中的终端。然后将产品返回到getProductById函数,但是不知何故,这里接收的值是不确定的。

getProductById

exports.getProductById = async (req, res) => {
console.log('\n#### ProductService#getProductById ####')
const id = req.params.id;

try {
    let product = await fetchProductFromCache(id);
    console.log('product from redis = ', product) //product here is unedfined

    if(product == null) {
        console.log('null product = ', product)
        product = await Product.findById(id);
        setProductInCache(id, product);
        console.log('PRODUCT FROM DB ');
    }                
    res.status(200).json(product);
    return;
} catch (error) {
    new ErrorHandler(res, error);
}
}

fetchProductFromCache

const fetchProductFromCache = async (id) => {
await redisClient.getProduct(id,  (error, product) => {
    if (error) {
        console.log('error', error);
        throw error;
    } else if(product) {
        console.log('PRODUCT FROM CACHE ', product); //valid product is logged   
        return product; //product returned to getProductById
    } else {
        console.log('NO PRODUCT FROM CACHE ');    
        return null;
    }            
});
}

2 个答案:

答案 0 :(得分:1)

那是因为您的fetchProducFromCache存在问题。 (阅读评论)

const fetchProductFromCache = async (id) => {
  // ** Here redisClient.getProduct expects 2nd parameter to be a callback which you've passed as annonymous function
  // let's name it cb
  await redisClient.getProduct(id,  (error, product) => {
    ...
    } else if(product) {
      console.log('PRODUCT FROM CACHE ', product); //valid product is logged
      // This returns to cb not to fetchProductFromCache.   
      return product; //product returned to getProductById
    ...
}

cb中执行redisClient.getProductfuture

您的let product = await fetchProductFromCache(id)中的这一行getProductById解析为undefined(在这里就是这种情况),因为您没有从fetchProductFromCache返回任何内容。这是因为Javascript对所有函数隐式返回undefined而不返回。

请注意,cb内部的返回值将返回cb函数,不返回 fetchProductFromCache

您可以通过使fetchProductFromCache返回Promise来实现您想要达到的目标:

const fetchProductFromCache = async (id) => {
  return new Promise((resolve, reject) => {
    redisClient.getProduct(id,  (error, product) => {
      if (error) {
        console.log('error', error);
        reject(error);
      } else if(product) {
        console.log('PRODUCT FROM CACHE ', product); //valid product is logged   
        resolve(product); //product returned to getProductById
      } else {
        console.log('NO PRODUCT FROM CACHE ');    
        resolve(null);
      }            
    });
  });
}

答案 1 :(得分:0)

Looks to me like you're returning from your redisClient.getProduct(), but not from your fetchProductFromCache(). As in your inner function is returning a value, but that value isn't being returned to the outer function, so the outer function is returning undefined.