如何在javascript中从promise返回值?

jogvjijk  于 2022-10-30  发布在  Java
关注(0)|答案(2)|浏览(191)

我是一个相当新的工作与承诺,现在我卡住了。我读了一些文章,所以职位,但我不能得到我的头周围。
我有一个简单的API,它返回一个人的数组和一些属性,如firstname,lastname和d.o.b.。我想检查未来10天内的生日。现在我被返回一个承诺的函数卡住了。我想让API返回一个数组,其中一个数组为人,一个数组为nextBirthdays。
如何解决承诺问题?
(我知道计算日期的部分不是最优雅的方法)

router.get('/', async(req, res) => {

    try {
        const contacts = await Contact.find()

        // Returns promise, but want array
        const nextBirthdays = getNextBirthdays(contacts)

        var promise = Promise.resolve(nextBirthdays);

        promise.then(function(val) {
            console.log(val);
        });

        res.json({ contacts, nextBirthdays })

    } catch (error) {
        res.status(500).json({ message: error.message })
    }
})

async function getNextBirthdays(contacts) {

    contacts.forEach(async(contact) => {

        let daysTillBirthday = await getDaysTillBirthday(contact.dob)

        if (daysTillBirthday < 10 && daysTillBirthday > 0) {
            console.log(`${contact.firstname}'s birthday is in ${daysTillBirthday} days`)
            nextBirthdays.push({
                firstname: contact.firstname,
                days: daysTillBirthday
            })
        }

        // Returns object with next birthdays
        return nextBirthdays

    })
}

async function getDaysTillBirthday(_birthday) {
    const birthday = await birthdayDayOfYear(_birthday)
    const today = await dayOfTheYear()
    const days = birthday - today
    return await days;
}

async function birthdayDayOfYear(date) {
    const now = date;
    const start = new Date(now.getFullYear(), 0, 0);
    const diff = now - start;
    const oneDay = 1000 * 60 * 60 * 24;
    const day = Math.floor(diff / oneDay);
    return await day
}

async function dayOfTheYear() {
    const now = new Date();
    const start = new Date(now.getFullYear(), 0, 0);
    const diff = now - start;
    const oneDay = 1000 * 60 * 60 * 24;
    const day = Math.floor(diff / oneDay);
    return await day
}
vxf3dgd4

vxf3dgd41#

您的程式码应该如下所示:

router.get('/', async (req, res) => {
  try {
    const contacts = await Contact.find()

    const nextBirthdays = getNextBirthdays(contacts)

    res.json({ contacts, nextBirthdays });
  } catch (error) {
    res.status(500).json({ message: error.message })
  }
})

function getNextBirthdays(contacts) {
  let nextBirthdays = [];
  contacts.forEach(contact => {

    let daysTillBirthday = getDaysTillBirthday(contact.dob)

    if (daysTillBirthday < 10 && daysTillBirthday > 0) {
      console.log(`${contact.firstname}'s birthday is in ${daysTillBirthday} days`)
      nextBirthdays.push({
        firstname: contact.firstname,
        days: daysTillBirthday
      })
    }
  })

  // Returns object with next birthdays
  return nextBirthdays
}

function getDaysTillBirthday(_birthday) {
  const birthday = birthdayDayOfYear(_birthday);
  const today = dayOfTheYear();
  return birthday - today;
}

function birthdayDayOfYear(date) {
  const now = date;
  const start = new Date(now.getFullYear(), 0, 0);
  const diff = now - start;
  const oneDay = 1000 * 60 * 60 * 24;
  return Math.floor(diff / oneDay);
}

function dayOfTheYear() {
  const now = new Date();
  const start = new Date(now.getFullYear(), 0, 0);
  const diff = now - start;
  const oneDay = 1000 * 60 * 60 * 24;
  return Math.floor(diff / oneDay);
}

module.exports = router;
ebdffaop

ebdffaop2#

所有调用生日的实用函数都可以写成同步函数,因为不需要像Contacts.find()那样“等待”结果;它们只是立即返回的算术运算。
尽管您 * 可以 * 将这些函数编写为异步函数,但这是不必要的,因此只需从所有这些函数中删除所有async修饰符,然后在return语句中删除所有await
然后删除forEach循环中的async,该循环用于构造生日结果数组。
因此,需要理解的关键是,您的生日计算可以同步完成,因此根本不需要解析任何承诺。要了解如何解析承诺,您 * 可以 * 将函数编写为如下异步函数,以dayOfTheYear为例:

function dayOfTheYear() {
  return new Promise((resolve) => {
    const now = new Date();
    const start = new Date(now.getFullYear(), 0, 0);
    const diff = now - start;
    const oneDay = 1000 * 60 * 60 * 24;
    const day = Math.floor(diff / oneDay);

    resolve(day);      // this is you resolving the promise you return
  });
}

如果我们要使用上面的函数,则有两种不同的方法:

dayOfTheYear()
     .then( (resolvedValue) => console.log(resolvedValue) )

resolvedValue是在调用resolve(day)时在函数中解析的内容。
或者,您可以使用await来代替then函数传入回调:

// assuming this code is in a function declared as async

  const resolvedValue = await dayOfTheYear();

因此,从上面可以看到,来自异步函数的return语句与来自Promise回调的resolve调用执行相同的操作。
最后一件事:从代码中可以明显看出,你对函数声明为async感到困惑。如果你要使用await来等待promise解析,你就声明了一个async函数。如果你不声明async,你就不能等待任何东西。但是你只能等待promise。
在引擎盖下,所有这些都是承诺,所有承诺都只是回调。
希望这对你有帮助。

相关问题