2016-10-11 49 views
0

我想通过反复调用一个带有一个键的函数来优化多个昂贵的服务器调用,并返回一个对象的承诺。解析后,该对象保证包含所需的键+某个值,并且可以包含其他不相关的键。该函数将:在JS中合并多个去抖动承诺

  • 在第一次通话中,创建一个承诺
  • 在每次调用,累积密钥发送给服务器
  • 所有调用返回了同样的承诺,直至安静的时间为100ms
  • 时呼叫服务器处理目前为止积累的所有密钥
  • 如果发出新的呼叫,即使服务器尚未响应,通过启动一个呼叫将其视为“第一个呼叫”带有自己的一组待定密钥的新承诺
  • 当服务器通话返回时,解决待处理的承诺

是否有任何NPM库会对此有所帮助,还是应该从头开始编写?

+0

关于“保证”部分 - 如果合并承诺由于通信故障拒绝,承诺的所有收件人可以赶上拒绝。但是如果一个特定的密钥是未知的,有效密钥的接收者应该继续。所以我的建议是从个人无效密钥的服务器返回一个无效值。否则,算法看起来很好(28行代码模拟;-)) – traktor53

回答

0

搜索“NPM使用单个承诺整合服务器请求”或“...累积服务器请求...”没有任何明显变化。我将使用评论中提到的ES6承诺共享样机代码,或许在没有其他建议的情况下形成解决方案的基础。因为,不保证等...

/******* application code ********/ 

function requestKeys(keyArray) { 
    // promise an oject for values of keys in keyArray: 
    // use asynchronous code to get values for keys in keyArray, 
    // return a promise for the parsed result object. 
    // ... 
} 

const latency = 100; // maximum latency between getting a key and making a request 

/******** generic code *********/ 

var getKey = ((requestKeys, latency) => { 
    // return a function to return a promise of a key value object 
    var promise = null; 
    var resolve = null; 
    var reject = null; 
    var pendingKeys = null; 

    var defer =() => { 
     promise = new Promise((r,j) => {resolve = r; reject = j}); 
     pendingKeys = []; 
    }; 

    var running = false; 
    var timesUp =() => { 
     resolve(requestKeys(pendingKeys)); 
     running = false; 
    } 
    var addKey = (key) => { 
     if(! running) { 
      defer(); 
      setTimeout(timesUp, latency); 
      running = true; 
     } 
     pendingKeys.push(key); 
     return promise; 
    } 
    return addKey; 
})(requestKeys, latency); 


/******* test code *******/ 

// redefine requestKeys to promise an object with key strings as key values, 
// resolve the return promise synchronously for testing: 

function requestKeys(keyArray) { 
    var keyObj = keyArray.reduce(((obj, v) => ((obj[v] = v), obj)), {}); 
    return new Promise((resolve, reject) => resolve(keyObj)); 
} 

var log = obj => console.log(JSON.stringify(obj)); 

// get two keys quickly 
getKey("holas").then(log); 
getKey("buono").then(log); 

// wait and get another 
setTimeout(function(){getKey('later').then(log)}, 500);