寻找与locking和更新调度有关的一个或两个节点模块

有些人会认为这个模块太单纯了,或者几乎把它放在一个leftPad类中,但是在npm中有太多的东西,我感觉这两个要求都被覆盖了,所以很想看看其他人完成了。 我inheritance了这个具有这种长时间更新function的代码库,并且有许多步骤。 它有一个自定义的locking标志,半成立过期,但实际上没有到期代码。 无论如何,主要的是要防止更新发生,而其他事情正在发生。 除了有时我们知道我们肯定需要尽快更新,但在当前更新的中间不正确。 这东西实际上并不工作。 所以我正在寻找一个或两个模块来做两件事情:

  1. 一个到期的locking,两个不同的长时间运行的函数(可以调用其他带callback的函数)可以用来确保它们不会彼此

  2. 一个简单的模块/函数,说'现在做这个函数,或者在它完成当前运行后再次运行'。

或者,在这种情况下,处理这两种情况的东西实际上可能是有意义的,尽pipe从我的描述来看,他们与对方的关系可能并不明显。

有效期限是,如果有一些情况我不希望长时间导致锁不能被删除,我们不想被永久卡住。

这里是一个例子:

function update() { // if we are trading, wait until that is done // if currently updating, skip it or schedule another one right // after, but only need one more, not a queue of updates // make a bunch of callbacks or a promise chain, takes a few seconds // in some cases we will find that we need to do one more update // immediately after all of this finishes, but not until the end } // ...some other places that want to call update function trade() { // trade happens sort of sporadically when the tick event fires // if we are updating, wait until we are done // make a bunch of callbacks or a promise chain, takes a few seconds // at the end we need to call update // but it can't update if it is already updating } 

 var Promise = require('bluebird'); // note using a bluebird type of promise const tradeQueue = []; var currentlyTrading = false; var currentlyUpdating = false; var pendingUpdate = null; var queuedUpdatePromiseDetails = null; // returns a promise that returns void, the promise will return // when either the currently executing update finishes, or a fresh one // does function update() { var test = Math.floor(Math.random() * 1000); console.log(test, 'update call'); if (!pendingUpdate) { pendingUpdate = new Promise(function (resolve, reject) { queuedUpdatePromiseDetails = { resolve: resolve, reject: reject, test: test }; if (currentlyTrading) { console.log(test, 'setting update to pending'); } else { // perform update, in callback call resolve() if no err, otherwise reject(err) console.log(test, 'running update'); currentlyUpdating = true; setTimeout(resolve, 100); } }).finally(function () { currentlyUpdating = false; console.log(test, 'update call complete'); pendingUpdate = null; queuedUpdatePromiseDetails = null; runPendingTradeOrUpdate(); }); } else { console.log(test, 'returning existing update promise', queuedUpdatePromiseDetails.test); } return pendingUpdate; } // returns a promise that completes when this // new trade finishes function trade(param) { var test = Math.floor(Math.random() * 1000); console.log(test, 'trade call'); return new Promise(function (resolve, reject) { if (currentlyTrading || currentlyUpdating) { console.log(test, 'queued trade') var newTrade = { param: param, resolve: resolve, reject: reject, test: test }; tradeQueue.push(newTrade); } else { currentlyTrading = true; console.log(test, 'beginning trade run'); // perform trade, in callback call resolve() if no error, otherwise reject(err) setTimeout(resolve, 100); } }).finally(function () { console.log(test, 'trade call complete'); // note that this bit is run for every single trade currentlyTrading = false; runPendingTradeOrUpdate(); }); } // dequeue next trade and run it function runPendingTradeOrUpdate() { if (queuedUpdatePromiseDetails && !currentlyUpdating && !currentlyTrading) { // perform update, in callback call resolve() if no err, otherwise reject(err) console.log(queuedUpdatePromiseDetails.test, 'running pending update'); currentlyUpdating = true; setTimeout(queuedUpdatePromiseDetails.resolve, 100); } else { if (tradeQueue.length > 0 && !currentlyTrading) { var nextTrade = tradeQueue.shift(); console.log(nextTrade.test, 'calling queued trade'); trade(nextTrade.param).then(nextTrade.resolve).catch(nextTrade.reject); } } } var runRandomly = function () { setTimeout(function () { update(); }, Math.floor(Math.random() * 300)) setTimeout(function () { trade(null); }, Math.floor(Math.random() * 300)) setTimeout(function () { runRandomly(); }, Math.floor(Math.random() * 300)) } runRandomly(); 

好的,非常感谢你的帮助。

这就是我决定我需要做的事情:我现在或者再创build一个非常简单的模块,并且使用现有的带有maxPendingfunction的locking锁而不是过期时间。

我使用这两个模块的方式与自述文件中的示例相同。