我有一项返回一些翻译的服务。它发出本质上是异步的顶点调用并返回翻译。每次获得一组结果时,我都会将翻译内容存储在会话存储中,而下次调用时,我会先在缓存的翻译内容中进行检查,如果可用,我会返回。当用户为同一组值发送多个翻译请求时,就会出现问题。为此,我一直在跟踪顶点调用。但是我不确定如何使我的请求等待上一个顶点调用结束并返回结果。
这是服务代码。
let labelQueue = [];
let labelMap;
let requestCustomLabels = function(labelsArr, language) {
return new Promise(function(resolve, reject) {
let labelsArray = [...labelsArr];
let returnedLabels = {};
let cachedLabels = JSON.parse(sessionStorage.getItem("customLabels")) || {};
labelMap = { ...cachedLabels };
if (Object.keys(labelMap).length > 0) {
labelsArray.forEach(item => {
if (Object.keys(labelMap).indexOf(item) > -1) {
labelsArray = labelsArray.filter(label => label !== item);
//push the available lables inside returnedLabels
returnedLabels[item] = labelMap[item];
}
});
}
if (Object.keys(returnedLabels).length === labelsArr.length) {
resolve(returnedLabels);
}
if (labelQueue.length && labelsArray.length) {
labelsArray.forEach(item => {
if (labelQueue.indexOf(item) > -1) {
labelsArray = labelsArray.filter(label => label !== item);
}
});
}
if (labelsArray.length) {
// store labels to the queue
labelsArray.forEach(label => {
labelQueue.push(label);
});
// then make call to apex for the result and store it inside returnedLabels & localmap and remove them from labelsQueue
fetchLabels(labelsArray, returnedLabels, language).then(
labelsReturned => {
returnedLabels = { ...returnedLabels, ...labelsReturned };
resolve(returnedLabels);
}
);
} else {
// wait for apex to return the call;
}
});
};
let fetchLabels = function(labelsArray, returnedLabels, language) {
return new Promise(function(resolve, reject) {
getUserProfile().then(function(userData) {
language = language || userData.language;
getCustomLabel(labelsArray, language)
.then(res => {
let labels = JSON.parse(res).data;
for (const key in labels) {
if (key !== "language" && key !== "totalSize") {
//when the apex call returns remove the labels from the label Queue.
labelQueue = labelQueue.filter(label => label !== key);
returnedLabels[key] = labels[key];
labelMap[key] = labels[key];
}
}
// store localsMap to the storage
sessionStorage.setItem("customLabels", JSON.stringify(labelMap));
resolve(returnedLabels);
})
.catch(function(error) {
console.error("error : ", error);
reject(error);
});
});
});
};
答案 0 :(得分:0)
我实际上编写了此脚本,主要用于获取在影子dom应用程序中从页面上的多个元素调用的语言文件。
您需要:
兑现承诺。
var ajaxQueue = {};
/**
* @description Avoids unnecessary calls to server
* @param {String} url The api call
* @param {String} method 'GET', 'POST', 'PUT', 'DELETE'
* @param {String} data If sending data through POST/PUT
*/
function queueAJAXCalls(url, method, data) {
var property = FXAjaxBehavior.getQueueProperty(url, method);
if (firstTimeRequesting(property)) { // 1
var ajaxPromise = someGeneralCodeForFetchingAjaxData(url, method, data) // 2
.then(function(serverData) {
removeFromAJAXQueue(property); // 5
return serverData;
}).catch(function(error) {
removeFromAJAXQueue(property); // 5
console.warn(error);
return false;
});
storeInAJAXQueue(property, ajaxPromise); // 3
}
return getAJAXFromQueue(property); // 4
}
function getQueueProperty(url, method) {
return encodeURIComponent(method + url);
}
function firstTimeRequesting(property) {
return !ajaxQueue[property];
}
function removeFromAJAXQueue(property) {
delete ajaxQueue[property];
}
function storeInAJAXQueue(property, ajaxPromise) {
ajaxQueue[property] = ajaxPromise;
}
function getAJAXFromQueue(property) {
return ajaxQueue[property];
}
示例:
queueAJAXCalls('http://somedomain.com/api/fetchstuff', 'GET')
.then(function(serverResponse) {
// do stuff, like using JSON.parse(serverResponse)
})
请注意在一个位置(即someGeneralCodeForFetchingAjaxData
)解析jsondata并返回数组和对象的危险,因为这意味着在一个位置更改数组/对象将在所有位置更改它。
我想您也可以使用Service Worker来代替实施此操作。