You might have close
expect an object be returned from closeCore
which had parameters like these:
return {timeout: 800, callback: function () {/*....will execute after a timeout..*/}};
or:
return {callback: function () { /*...will be immediately executed...*/}};
or:
return function () { /*...will be immediately executed...*/};
...and then call their timeout for them (if any), and then after your timeout executed their callback, then call dispose
for them.
The relevant part of your close
code might look like:
function close() {
var ccObj = closeCore();
var ccIsObj = ccObj && typeof ccObj === 'object';
var callback = typeof ccObj === 'function' ? ccObj : (ccIsObj ? ccObj.callback : null);
if (ccIsObj && ccObj.timeout) {
if (!callback) {
throw 'You must implement a callback when supplying a timeout';
}
setTimeout(function () {
callback();
dispose();
}, ccObj.timeout);
}
else {
if (callback) {callback();}
dispose();
}
}
But if you want to allow the user to make arbitrary asynchronous calls of their own (such as Ajax), while you could instead allow the returning of a promise to which you added the dispose
call, you wouldn't have a guarantee that the deriver would ensure the promise completed. You could automatically cancel the promise after a certain period of time, but you couldn't magically know when the deriving code was meant to finish unless again you abstracted this.