【问题标题】:How do I return value from promise in javascript?如何从 JavaScript 中的 Promise 返回值?
【发布时间】:2021-02-26 02:01:26
【问题描述】:

我对使用 Promise 还很陌生,现在我陷入了困境。我阅读了一些文章和 SO 帖子,但我无法理解它。

我有一个简单的 API,它返回一组人员和一些属性,如名字、姓氏和 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
}

【问题讨论】:

  • 看起来你的任何函数都不需要异步。
  • awaitforEach 中不起作用
  • 你的getNextBirthdays实际上并没有返回任何东西,因为forEach总是返回undefined
  • @DanCantir,它有效,只是没有按照您的想法做。
  • @DannisFink 观看此视频:youtube.com/watch?v=8aGhZQkoFbQ

标签: javascript node.js async-await promise es6-promise


【解决方案1】:

您的代码应如下所示:

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;

【讨论】:

【解决方案2】:

所有用于调用生日的实用函数都可以编写为同步函数,因为您不需要像 Contacts.find() 那样“等待”结果;它们只是立即返回的算术运算。

虽然您可以将这些写为异步函数,但这是不必要的,因此只需从所有这些函数中删除所有async 修饰符,然后在返回语句中删除所有awaits。

然后在构造生日结果数组的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 调用执行相同的操作。

最后一件事:从您的代码中可以明显看出,您对将函数声明为异步感到困惑。如果您将使用 await 来等待 Promise 解决,则声明一个函数 async。如果你不声明异步,你就不能等待任何东西。但你永远只能等待 Promises。

在底层,所有这些都是 Promise,所有 Promises 都只是回调。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 2021-08-25
    • 1970-01-01
    • 2021-08-08
    相关资源
    最近更新 更多