为什么我的数组在地图内时有项目,但是在地图运行后却为空?

时间:2018-11-14 15:54:59

标签: javascript arrays node.js express mongoose

我试图用特定用户的收藏列表填充Express User控制器中的数组。 map()运行时,阵列控制台会按我期望的方式注销对象。但是map()完成后,清单将作为一个空数组返回到客户端。我想念什么吗?

此处的目标是在MongoDB中查询用户ID,并返回用户的收藏夹数组,该数组只是用于列表的ID字符串数组。如果用户在其收藏夹数组中有项目,它将继续获取那些清单的数据,然后将其返回给React。

userController.getFavorites = (req, res) => {
  let favorites = [];
  let listings = [];
  const user = req.params.userID;
  console.log("USER:", user);

  if (true) { // in production this will check for the authenticated user ID. True is just for testing with postman
    User.findById(user).exec((err, user) => {
      if (err) {
        console.error("Error!", err);
        return;
      } else {
        favorites = favorites.concat(user.favorites);
        console.log(user.favorites, favorites);

        if (favorites.length > 0) {
          favorites.map((favorite) => {
            Place.findById(favorite).exec((err, listing) => {
              if (err) console.log("Error!", err);
              listings.push(listing);
              console.log("SINGLE LISTING", listing);
              console.log("INSIDE MAP ALL LISTINGS:", listings); // this logs as expected with all of the listings.
            });
          });

          console.log("OUTSIDE MAP ALL LISTINGS", listings); // this returns empty
          res.send(listings); // empty as well obviously
        }
      }
    });
  }
}

1 个答案:

答案 0 :(得分:0)

尝试一下:

const createListing = (favorites) => {
  return new Promise((resolve, reject) => {
    let listings = [];
    for (let i = 0; i < favorites.length; i++) {
      Place.findById(favorites[i]).exec((err, listing) => {
        if (err) {
          reject(err);
          return;
        }
        console.log(listing);
        listings.push(listing);
      })
      if (i === favorites.length - 1) {
        resolve(listings);
        return;
      }
    }
  })
}

userController.getFavorites = (req, res) => {
  let favorites = [];
  let listings = [];
  const user = req.params.userID;
  console.log("USER:", user);

  if (true) { // in production this will check for the authenticated user ID. True is just for testing with postman
    User.findById(user).exec((err, user) => {
      if (err) {
        console.error("Error!", err);
        return;
      } else {
        favorites = favorites.concat(user.favorites);
        console.log(user.favorites, favorites);

        if (favorites.length > 0) {
          createListing(favorites)
            .then(data => {
              console.log(data);
              res.send(data)
            })
            .catch(err => {
              console.log(err);
            })
        }
      }
    });
  }
}

首先尝试上面的代码,然后再尝试下面的代码:

const findFavorite = (favorite) => {
  return new Promise((resolve) => {
    Place.findById(favorite).exec((err, listing) => {
      if (err) {
        resolve({ error: err });
        return;
      }
      resolve({ data: listing });
      return;
    })
  })
}

const createListing = (favorites) => {
  return new Promise(async (resolve, reject) => {
    let listings = [];
    for (let i = 0; i < favorites.length; i++) {
      let res = await findFavorite(favorites[i]);
      if (res.error) {
        reject(res.error);
        return;
      }
      listings.push(res.data);
    }
    resolve(listings);
    return;
  })
}

userController.getFavorites = (req, res) => {
  let favorites = [];
  const user = req.params.userID;
  console.log("USER:", user);

  if (true) { // in production this will check for the authenticated user ID. True is just for testing with postman
    User.findById(user).exec((err, user) => {
      if (err) {
        console.error("Error!", err);
        return;
      } else {
        favorites = favorites.concat(user.favorites);
        console.log(user.favorites, favorites);

        if (favorites.length > 0) {
          createListing(favorites)
            .then(data => {
              console.log(data);
              res.send(data)
            })
            .catch(err => {
              console.log(err);
            })
        }
      }
    });
  }

}