Using jQuery promises I do the following to manage a situation where I have multiple instances where I need to call for external resource, but I don't want to call for the same external resource more than once.
{ "somedata": "...", "department": "https://api.../departments/1000", }
Already deep down in separate function calls for each data object I wish to coordinate all calls to the same resources. I don't want to fetch department name for "department 1000" multiple times.
I save promises OR a returned result in a dictionary and reuse them.
a. If it is a promise, I return the same promise to be reused by the caller.
b. If it is a fetched value, I resolve the promise asynchronous by using a timeout.
Here is the code:
var Departments = {};
function getDepartmentName(id){
var dfd = new $.Deferred();
var promise = dfd.promise();
if(id in Departments){
if(typeof Departments[id] == 'object'){
return Departments[id];//reuse the promise
}else{//department name is a string
setTimeout(function(){ dfd.resolve(Departments[id]); }, 0);
}
}
else{
Departments[id] = promise;//Set dictionary value to the promise
var dPromise = FetchDepartment('https://api.../departments/'+id);
$.when(dPromise).then(
function(departmentName){
Departments[id] = departmentName;//Re-set dictionary value to the fetched value
dfd.resolve(departmentName);
},
function(err){
delete Departments[id];
dfd.reject('Call failed');
}
);
}
return promise;
}
It seems to work but I am concerned whether this is such a great design. I have a few questions.
答案 0 :(得分:1)
我将诺言或返回的结果保存在字典中,然后重用它们。如果它是一个获取的值,我将通过使用超时来异步解决Promise。
不要那么复杂。这的行为与您仅保留承诺并仅返回承诺的情况完全相同,而不是在最初的承诺完成后为呼叫创建新的承诺。
还有avoid deferreds,当您已经在处理承诺时。
var Departments = {};
function getDepartmentName(id) {
if (id in Departments){
return Departments[id]; //reuse the promise
} else {
var promise = FetchDepartment('https://api.../departments/'+id).then(null, function(err){
delete Departments[id]; // allow retries
throw err;
});
return Departments[id] = promise;
}
}
重用这样的一个Promise实例是否正确,在该实例中多个调用者都对同一个Promise对象的.then进行调用?
是的,这完全可以。他们的回调将按照与发起then
的调用相同的顺序安排。