asyncObject = {
waiters: new Map(),
elements: new Map(),
getElement: async function (key) {
if(this.elements.has(key)) return this.elements.get(key);
return new Promise(res => this.waiters.set(key, [...(this.waiters.get(key) ?? []), res]));
},
setElement: function(key, value) {
this.elements.set(key, Promise.resolve(value));
if (this.waiters.has(key)) {
this.waiters.get(key).forEach(res => res(value));
this.waiters.delete(key);
}
}
}
YXN5bmNPYmplY3QgPSB7Cgl3YWl0ZXJzOiBuZXcgTWFwKCksCgllbGVtZW50czogbmV3IE1hcCgpLAoJZ2V0RWxlbWVudDogYXN5bmMgZnVuY3Rpb24gKGtleSkgewoJICBpZih0aGlzLmVsZW1lbnRzLmhhcyhrZXkpKSByZXR1cm4gdGhpcy5lbGVtZW50cy5nZXQoa2V5KTsKCSAgcmV0dXJuIG5ldyBQcm9taXNlKHJlcyA9PiB0aGlzLndhaXRlcnMuc2V0KGtleSwgWy4uLih0aGlzLndhaXRlcnMuZ2V0KGtleSkgPz8gW10pLCByZXNdKSk7Cgl9LAoJc2V0RWxlbWVudDogZnVuY3Rpb24oa2V5LCB2YWx1ZSkgewoJICB0aGlzLmVsZW1lbnRzLnNldChrZXksIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkpOwoJICBpZiAodGhpcy53YWl0ZXJzLmhhcyhrZXkpKSB7CgkgICAgdGhpcy53YWl0ZXJzLmdldChrZXkpLmZvckVhY2gocmVzID0+IHJlcyh2YWx1ZSkpOwoJICAgIHRoaXMud2FpdGVycy5kZWxldGUoa2V5KTsKCSAgfQoJfQp9