简体   繁体   English

Javascript重用承诺来管理多个调用

[英]Javascript reusing promise to manage multiple calls

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. 使用jQuery Promise,我可以执行以下操作来处理以下情况:我有多个实例需要调用外部资源,但是我不想多次调用同一外部资源。

  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). 初始REST调用使我获得了多个数据对象,并带有对附加信息的引用(在示例“部门”属性中提供了对可以在何处找到有关部门的更多信息的引用)。

{ "somedata": "...", "department": " https://api.../departments/1000 ", } {“ somedata”:“ ...”,“部门”:“ 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. 我不想多次获取“部门1000”的部门名称。

  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. b。 If it is a fetched value, I resolve the promise asynchronous by using a timeout. 如果它是一个获取的值,我将通过使用超时来异步解决Promise。

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? 像这样重用一个Promise实例是否正确? 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. 多个调用者都对同一个Promise对象的.then进行了调用,这似乎工作良好,但是我不知道当Promise解决时jQuery如何链接所有这些接收者。

I save promises OR a returned result in a dictionary and reuse them. 我将诺言或返回的结果保存在字典中,然后重用它们。 If it is a fetched value, I resolve the promise asynchronous by using a timeout. 如果它是一个获取的值,我将通过使用超时来异步解决Promise。

Don't make it so complicated. 不要这么复杂。 This behaves exactly the same as if you just kept the promise and only returned it, instead of creating new promises for calls after the initial one fulfilled. 这的行为与您仅保留承诺并仅返回承诺的行为完全相同,而不是在最初的承诺完成后为呼叫创建新的承诺。

Also, avoid deferreds when you are already dealing with promises. 另外,在已经处理诺言的情况下,请避免延期

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;
    }
}

Is it correct to reuse a promise instance like this, where multiple callers make a call to .then of the same promise object? 重用这样的一个Promise实例是否正确,在该实例中多个调用者对同一个Promise对象的.then进行调用?

Yes, this is totally fine. 是的,这完全可以。 Their callbacks will be scheduled in the same order as the originating calls to then . 他们的回调将按照与then发起调用相同的顺序进行调度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM