【发布时间】:2020-08-17 02:08:54
【问题描述】:
我的客户端 Javascript 应用程序需要来自服务器端的特定数据结构(“列表”)。应用程序中的几个不同位置需要访问列表。启动时,这些地方都会发出请求,这会导致对服务器的多个并发请求,以获取相同的数据结构。
我想只向服务器发出一个请求,并让所有请求者简单地得到一个承诺,当请求返回时解决。
我认为方法是创建一个数组或一组承诺。如果第一个请求正在进行中,那么每个后续请求都会导致创建一个 Promise 并将其添加到堆栈中。当响应返回时,系统会遍历堆栈并使用结果解析所有的 Promise。
问题是我无法找出正确的语法来让它工作。这是我目前所拥有的:
let lists = [];
let loading = false;
let promises = [];
function getLists() {
if (lists.length > 0) {
// return cached copy
return Promise.resolve(lists);
}
/*
This method can get called several times in quick succession on startup.
To prevent sending multiple requests to the server, we maintain
a stack of promises. If there is already a request in-flight, then just
add a promise to the stack and return it. Then resolve all promises
in the stack when the request returns.
*/
let prom = new Promise(); // BAD, NOT ALLOWED
promises.push(prom);
if (!loading) {
callListsApi(); // async call, resolves promises
}
return prom;
}
function callListsApi() {
loading = true;
axios.get("/lists").then(
response => {
loading = false;
if (!response.data || response.data.length == 0) {
lists = [];
} else {
lists = response.data;
}
for (let i = 0; i < promises.length; i++) {
promises[i].resolve(lists); // give all the callers their lists
}
promises = [];
},
error => {
loading = false;
util.handleAxiosError(error);
let msg = util.getAxiosErrorText(error);
for (let i = 0; i < promises.length; i++) {
promises[i].reject(msg);
}
promises = [];
}
);
}
这是行不通的,因为你不能创建一个裸 Promise() 而不在其中放入某种 executor 函数。
我怎样才能重写它以使其正常工作?
【问题讨论】:
标签: javascript ajax concurrency promise axios