Javascript reusing promise to manage multiple calls

时间:2018-07-24 10:12:25

标签: javascript promise

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.

  1. Initital REST calls gets me multiple data objects with references to additional information (in the example "department" property gives a reference to where I can find more info about the department).

{ "somedata": "...", "department": "https://api.../departments/1000", }

  1. 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.

  2. 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.

  1. Is there some promise functionality I should use instead?
  2. Are there any situations where things might happen in the wrong order?
  3. Is it correct to reuse a promise instance like this? Multiple callers make a call to .then of the same promise object, and it seems to work well, but I don't know how jQuery chain all these recipients when the promise is resolved.

1 个答案:

答案 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的调用相同的顺序安排。