如何让我的函数在 returns 另一个调用之前等待
How to make my function wait before it returns another call
我有一项服务可以 return 进行一些翻译。它进行本质上异步的 apex 调用和 returns 翻译。每次我得到一组结果时,我都会将翻译存储在会话存储中,下次来电时,我首先会在缓存的翻译中检查它,如果可用,然后我 return。当用户为同一组值发送多个翻译请求时,问题就来了。为此,我正在跟踪已经在进行中的顶点调用。但是我不确定如何让我的请求等待之前的 apex 调用结束和 return 结果。
这是服务代码。
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);
});
});
});
};
我实际上编写了这个脚本,主要是为了获取从影子页面上的多个元素调用的语言文件 dom 应用程序。
您需要:
- 检查承诺是否已存储。
- 将 ajax 承诺保存为变量。
- 存储变量,如果没有存储的话。
- 获取承诺,或返回存储的承诺。
删除承诺。
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)
})
注意在一个地方解析 jsondata 的危险,即在 someGeneralCodeForFetchingAjaxData
中,并返回数组和对象,因为这意味着在一个地方更改 array/object 会改变所有地方地点。
除了实现这个,我想你也可以使用 Service Worker.
我有一项服务可以 return 进行一些翻译。它进行本质上异步的 apex 调用和 returns 翻译。每次我得到一组结果时,我都会将翻译存储在会话存储中,下次来电时,我首先会在缓存的翻译中检查它,如果可用,然后我 return。当用户为同一组值发送多个翻译请求时,问题就来了。为此,我正在跟踪已经在进行中的顶点调用。但是我不确定如何让我的请求等待之前的 apex 调用结束和 return 结果。
这是服务代码。
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);
});
});
});
};
我实际上编写了这个脚本,主要是为了获取从影子页面上的多个元素调用的语言文件 dom 应用程序。
您需要:
- 检查承诺是否已存储。
- 将 ajax 承诺保存为变量。
- 存储变量,如果没有存储的话。
- 获取承诺,或返回存储的承诺。
删除承诺。
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)
})
注意在一个地方解析 jsondata 的危险,即在 someGeneralCodeForFetchingAjaxData
中,并返回数组和对象,因为这意味着在一个地方更改 array/object 会改变所有地方地点。
除了实现这个,我想你也可以使用 Service Worker.