我有以下代码
module.exports = async function (req, res) {
const station1 = await getStation('one')
const station2 = await getStation('two')
return { stations: [station1, station2] }
}
我可以保证在发送最终返回值时它肯定会同时包含station1
和station2
数据,或者我是否需要将函数调用包装在{{1}中}
答案 0 :(得分:6)
正如您所知,只有当两个return
承诺得到解决时才能保证getStation()
语句才会被执行。
然而,第二次调用getStation
只会在第一个承诺解决后才会发生,使它们串行运行。由于它们之间没有依赖关系,因此如果要并行运行它们,就可以获得性能。
尽管可以使用Promise.all
实现这一点,但您可以通过首先检索这两个承诺,然后再对它们执行await
来实现相同的目标:
module.exports = async function (req, res) {
const promise1 = getStation('one');
const promise2 = getStation('two');
return { stations: [await promise1, await promise2] }
}
现在两个电话都将在"同一个"时间,只有return
语句将等待两个承诺解决。这也在MDN's "simple example"中说明。
答案 1 :(得分:1)
await关键字实际上让你在代码行上“等待”,同时运行异步操作。
这意味着在解决异步操作之前,您不会继续执行下一行代码。如果您的代码与结果存在依赖关系,那么这很好。
示例:
const res1 = await doSomething();
if(res1.isValid)
{
console.log('do something with res1 result');
}
以下代码示例将等待三秒后解析的promise。检查日期打印到控制台以了解等待做什么:
async function f1() {
console.log(new Date());
// Resolve after three seconds
var p = new Promise(resolve => {
setTimeout(() => resolve({}),3000);
});
await p;
console.log(new Date());
}
f1();
BTW,在您的情况下,由于您不使用station1
的结果,因此最好使用Promise.all
并行工作。
检查此示例(它将按照您上面编码的方式运行3秒而不是4秒):
async function f1() {
console.log(new Date());
// Resolve after three seconds
var p1 = new Promise(resolve => {
setTimeout(() => resolve({a:1}),3000);
});
// Resolve after one second
var p2 = new Promise(resolve => {
setTimeout(() => resolve({a:2}),1000);
});
// Run them parallel - Max(three seconds, one second) -> three seconds.
var res = await Promise.all([p1,p2]);
console.log(new Date());
console.log('result:' + res);
}
f1();
答案 2 :(得分:1)
如果await getStation('one')
或await getStation('two')
中的任何一个失败,将从异步函数抛出异常。因此,您应始终从两个承诺中获得已解决的值。
您可以按如下方式重写您的功能,以使用Promise.all
module.exports = async function (req, res) {
try{
const [station1, station2] = await Promise.all([
getStation('one'),
getStation('two')
]);
return { stations: [station1, station2] };
} catch (e) {
throw e;
}
}