Javascript 解决未决的平行承诺

Javascript 解决未决的平行承诺,javascript,promise,hapijs,Javascript,Promise,Hapijs,我最近升级了一个HAPI安装到v17,它使用承诺,我面临着一个我不知道如何解决的情况。这不是HAPI特定的 当调用某个路由时,将进行检查,以查看是否缓存了特定服务调用的结果。如果是这样,我们将跳过调用并使用缓存的结果——否则,将进行服务调用,这涉及到承诺 问题是,如果服务器启动,结果没有被缓存,我们运行一个负载测试,突然会有大量的服务调用来获取结果,因为它们还没有被缓存,而大量的请求正好同时出现 我想做的是只让第一个请求触发服务调用,然后让所有后续请求等待(通过承诺?)该调用返回-然后可以解决所

我最近升级了一个HAPI安装到v17,它使用承诺,我面临着一个我不知道如何解决的情况。这不是HAPI特定的

当调用某个路由时,将进行检查,以查看是否缓存了特定服务调用的结果。如果是这样,我们将跳过调用并使用缓存的结果——否则,将进行服务调用,这涉及到承诺

问题是,如果服务器启动,结果没有被缓存,我们运行一个负载测试,突然会有大量的服务调用来获取结果,因为它们还没有被缓存,而大量的请求正好同时出现

我想做的是只让第一个请求触发服务调用,然后让所有后续请求等待(通过承诺?)该调用返回-然后可以解决所有未决承诺,让其他请求继续

我如何构建这个?在过去,使用回调时,我只需将回调添加到列表中,然后在返回结果后调用该列表中的所有回调。我是否可以做一些类似的事情,但在接到电话之前把承诺堆积起来,然后全部解决?我对承诺还是新手,所以很难想象它

目前,基本的简化逻辑是:

function getData() {
    return new Promise(...);
}

...

if (!data) {
    data = await getData();
}
return data;
如果数据没有被缓存,我不想只调用getData(),而是想在getData发送请求获取数据时设置一个标志,并让后续调用等待该请求完成以获取数据并继续,而不是再发送另一个请求


谢谢

您可以缓存promise本身,而不是缓存data+标志,以查看是否检索到数据

function loadData() {
    someOuterVariable = fetch(...).then(/*transforming data structure*/)
}

async function dataConsumer() {
    const data = await someOuterVariable; // does not matter if it has been retrieved or not
    .... 
}

async function anotherConsumer() {
    ....
    const item = (await someOuterVariable).filter(/* just an example of inline processing*/)
}
不管数据是否已经被检索到,承诺仍然是承诺


唯一的限制是-您可以使用新承诺更新
someOuterVariable
,但如果任何消费函数已经开始
等待
,它将从以前的承诺中获取旧数据。但根据您的描述,在履行承诺之前,您不需要替换承诺,是吗?

您可以缓存承诺本身,而不是缓存数据+标志,以查看是否检索到数据

function loadData() {
    someOuterVariable = fetch(...).then(/*transforming data structure*/)
}

async function dataConsumer() {
    const data = await someOuterVariable; // does not matter if it has been retrieved or not
    .... 
}

async function anotherConsumer() {
    ....
    const item = (await someOuterVariable).filter(/* just an example of inline processing*/)
}
不管数据是否已经被检索到,承诺仍然是承诺

唯一的限制是-您可以使用新承诺更新
someOuterVariable
,但如果任何消费函数已经开始
等待
,它将从以前的承诺中获取旧数据。但根据你的描述,在履行诺言之前,你不应该用它来代替诺言,是吗