Skip to content

Instantly share code, notes, and snippets.

@jfet97
Last active November 9, 2022 11:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfet97/ff4ecce9daac654c6cde3f83c6fa67c9 to your computer and use it in GitHub Desktop.
Save jfet97/ff4ecce9daac654c6cde3f83c6fa67c9 to your computer and use it in GitHub Desktop.
A simple implementation of a promise queue that is temporal independent
class asyncAwaiterQueue {
constructor(...values) {
this.promise = new Promise(resolve => {
this.resolve = resolve;
});
values.forEach(v => this.put(v));
}
put(value) {
// advance the tail
let resolveNext = null;
const nextPromise = new Promise(resolve => {
resolveNext = resolve;
});
this.resolve({
value: Promise.resolve(value), // normalize the value
nextPromise,
});
this.resolve = resolveNext;
}
get() {
// advance the head
const resultingPromise = this.promise.then(({ value }) => value);
const actualPromise = this.promise;
// defer next node resolution until the current is solved
// because the resultingPromise's value could be a long time running promise
this.promise = resultingPromise.then(() => actualPromise).then(({ nextPromise }) => nextPromise);
return resultingPromise;
}
}
class asyncDoubleAwaiterQueue {
constructor(...values) {
this.get_promise = new Promise((resolve) => {
this.get_resolve = resolve;
});
this.put_promise = new Promise((resolve) => {
this.put_resolve = resolve;
});
values.forEach((v) => this.put(v));
}
put(value) {
const v = Promise.resolve(value); // normalize the value
let get_resolve_next = null;
const get_promise_next = new Promise((resolve) => {
get_resolve_next = resolve;
});
this.get_resolve({
value: v,
get_promise_next,
});
this.get_resolve = get_resolve_next;
const current_put_promise = this.put_promise;
this.put_promise = this.put_promise.then(
({ put_promise_next }) => put_promise_next
);
return current_put_promise;
}
get() {
const resulting_get_promise = this.get_promise
.then(({ value }) => value)
.then((v) => {
let put_resolve_next = null;
const put_promise_next = new Promise((resolve) => {
put_resolve_next = resolve;
});
this.put_resolve({
put_promise_next,
});
this.put_resolve = put_resolve_next;
return v;
});
const current_get_promise = this.get_promise;
this.get_promise = resulting_get_promise
.then(() => current_get_promise)
.then(({ get_promise_next }) => get_promise_next);
return resulting_get_promise;
}
}
const queue = new asyncDoubleAwaiterQueue();
queue.get().then((v) => console.log(`Get 1 of ${v}`));
queue.get().then((v) => console.log(`Get 2 of ${v}`));
queue
.put(new Promise((res) => setTimeout(res, 10000, 1)))
.then((v) => console.log(`Put 1`));
queue
.put(new Promise((res) => setTimeout(res, 5000, 2)))
.then((v) => console.log(`Put 2`));
class AsyncQueue {
constructor(...values) {
this.promise = new Promise(resolve => {
this.resolve = resolve;
});
values.forEach(v => this.put(v));
}
put(value) {
// advance the tail
let resolveNext = null;
const nextPromise = new Promise(resolve => {
resolveNext = resolve;
});
this.resolve({
value,
nextPromise,
});
this.resolve = resolveNext;
}
get() {
// advance the head
const resultingPromise = this.promise.then(({ value }) => value);
this.promise = this.promise.then(({ nextPromise }) => nextPromise);
return resultingPromise;
}
}
@gangsthub
Copy link

Could you share same examples using this, please? (Possible use cases...)

@jfet97
Copy link
Author

jfet97 commented Dec 31, 2019

Could you share same examples using this, please? (Possible use cases...)

They are useful to implement streams, iteration queues for async gens and async gens related stuff (https://github.com/jfet97/aww), ecc.
More info here: https://github.com/kriskowal/gtor

@gangsthub
Copy link

I see! Thank you very much. I was clearer with the aww sample. And thanks for the gtor reference. I'll check it out 🙌

@jfet97
Copy link
Author

jfet97 commented Dec 31, 2019

I see! Thank you very much. I was clearer with the aww sample. And thanks for the gtor reference. I'll check it out 🙌

You're welcome 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment