You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow "defer after await" at any time before notification triggered #79
I realized today that some utility scripts I wrote are no longer working since the current version explicitly checks for and throws on defer after await. Reviewing when/why this might have gotten enforced it looks like I have a history of beating this drum already!
My use case boils down to essentially cases of "pagination" or "following linked lists asyncronously". I.e. the task I'm enqueuing does some work and only in the process of doing said work determines whether more work needs to be done. Thus my pattern is to create a queue, defer the initial task, and immediately awaitAll the eventual results.
My current workaround is to hack around the assertion:
const {queue:q} = require('d3-queue');
const _actualDefer = q.prototype.defer;
q.prototype.defer = function () {
var _origCall = this._call;
this._call = null;
var result = _actualDefer.apply(this, arguments);
this._call = _origCall;
return result;
};
My proposal would be that defer can be called at any time before the notification actually happens. Likely implementation would be something like:
const TOMBSTONE = Symbol("await called"); // NOTE: `Object.create(null);` for older JS engines would suffice
function maybeNotify(q) {
if (!q._active && q._call) {
var d = q._data;
q._data = undefined; // allow gc
q._call(q._error, d);
q._call = TOMBSTONE;
}
}
and replacing
if (this._call) throw new Error("defer after await");
with
if (this._call === TOMBSTONE) throw new Error("defer after await called");`
I can submit a PR including any ancillary doc/test changes if you'd be amenable to this behavior change.
The concern seemed to be primarily a documentation/specification issue. I guess outlawing the use case entirely simplifies that, but it prevents advanced usage. (Note: current me is not super sold on my original proposal where "the await/awaitAll callback is called every time the number of remaining tasks goes to 0" either as it would indeed be a pain to explain at best…)
Activity
natevw commentedon Jul 1, 2020
(Additional background)
The original discussions are all mixed up in some ancient stuff about zalgo and
thispassing, but for posterity:The concern seemed to be primarily a documentation/specification issue. I guess outlawing the use case entirely simplifies that, but it prevents advanced usage. (Note: current me is not super sold on my original proposal where "the await/awaitAll callback is called every time the number of remaining tasks goes to 0" either as it would indeed be a pain to explain at best…)
mbostock commentedon Jul 2, 2020
I’m not maintaining this library anymore. I recommend using promises and async/await.