我如何 return 从 javascript 中的承诺中获得价值?
How do I return value from promise in javascript?
我对使用 promises 还很陌生,现在我卡住了。我读了几篇文章和 SO 帖子,但我无法理解它。
我有一个简单的 API,其中 return 是一组人和一些属性,例如名字、姓氏和 d.o.b。我想检查未来 10 天内的生日。现在我坚持 returning 一个承诺的功能。我想要 API 到 return 一个数组,其中包含一个用于人的数组和一个用于 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
}
您的代码应如下所示:
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;
所有用于调用生日的实用函数都可以编写为同步函数,因为您不需要像 Contacts.find()
那样“等待”结果;它们只是立即 return 的算术运算。
尽管您可以将它们写成异步函数,但这是不必要的,所以只需从所有这些函数中删除所有 async
修饰符,然后删除所有 [= return 语句中的 15=]s。
然后删除 forEach
循环中的 async
,该循环构建生日结果数组。
所以要理解的关键是你的生日计算可以同步完成,所以根本不需要 resolve 任何 promise。要了解如何解决您的承诺,您 可以 将您的函数编写为异步函数,以您的 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)
时在函数中解决的问题。
或者不使用 then
函数传入回调,而是使用 await
:
// assuming this code is in a function declared as async
const resolvedValue = await dayOfTheYear();
所以从上面可以看出,异步函数中的 return
语句与 Promise 回调中的 resolve
调用执行相同的操作。
最后一件事:从您的代码中可以明显看出您对将函数声明为异步感到困惑。如果您将使用 await
来等待 Promise 解析,则声明一个函数异步。如果你不声明异步,你就不能等待任何事情。但是你只能等待承诺。
在幕后,所有这些都是 Promise,所有 Promise 都只是回调。
希望对您有所帮助。
我对使用 promises 还很陌生,现在我卡住了。我读了几篇文章和 SO 帖子,但我无法理解它。
我有一个简单的 API,其中 return 是一组人和一些属性,例如名字、姓氏和 d.o.b。我想检查未来 10 天内的生日。现在我坚持 returning 一个承诺的功能。我想要 API 到 return 一个数组,其中包含一个用于人的数组和一个用于 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
}
您的代码应如下所示:
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;
所有用于调用生日的实用函数都可以编写为同步函数,因为您不需要像 Contacts.find()
那样“等待”结果;它们只是立即 return 的算术运算。
尽管您可以将它们写成异步函数,但这是不必要的,所以只需从所有这些函数中删除所有 async
修饰符,然后删除所有 [= return 语句中的 15=]s。
然后删除 forEach
循环中的 async
,该循环构建生日结果数组。
所以要理解的关键是你的生日计算可以同步完成,所以根本不需要 resolve 任何 promise。要了解如何解决您的承诺,您 可以 将您的函数编写为异步函数,以您的 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)
时在函数中解决的问题。
或者不使用 then
函数传入回调,而是使用 await
:
// assuming this code is in a function declared as async
const resolvedValue = await dayOfTheYear();
所以从上面可以看出,异步函数中的 return
语句与 Promise 回调中的 resolve
调用执行相同的操作。
最后一件事:从您的代码中可以明显看出您对将函数声明为异步感到困惑。如果您将使用 await
来等待 Promise 解析,则声明一个函数异步。如果你不声明异步,你就不能等待任何事情。但是你只能等待承诺。
在幕后,所有这些都是 Promise,所有 Promise 都只是回调。
希望对您有所帮助。