I'm attempting to introduce a queue-type system to a JS class to allow for Async method chaining, ideally, I'd like to perform operations on the class instance using these async methods and return "this" instance.
export class Queue {
constructor() {
this.queue = Promise.resolve()
this.firstRequestStarted = false
this.firstRequestStatusCode = 0
this.secondRequestStarted = false
this.secondRequestStatusCode = 0
}
then(callback) {
callback(this.queue)
}
chain(callback) {
return this.queue = this.queue.then(callback)
}
first() {
this.chain(async () => {
try {
this.firstRequestStarted = true
const response = await axios.get("https://stackoverflow.com/questions")
this.firstRequestStatusCode = response.status
return this
}
catch (e) {
const { message = "" } = e || {}
return Promise.reject({ message })
}
})
return this
}
second() {
this.chain(async () => {
try {
this.secondRequestStarted = true
const response = await axios.get("https://stackoverflow.com/")
this.secondRequestStatusCode = response.status
return this
}
catch (e) {
const { message = "" } = e || {}
return Promise.reject({ message })
}
})
return this
}
}
Functions are added to the queue, and as we await them, the "then" method will handle their execution.
const x = await new Queue()
.first()
.second()
console.log(x)
The challenge I'm facing is that I can never actually get "this" (instance of Queue) back to x.
1) x === undefined
2) "Chaining cycle detected for promise #<Promise>"
or ( I haven't been able to track down where this one is coming from, node error)
3) finished with exit code 130 (interrupted by signal 2: SIGINT)
I have tried adding a "consume" method, which simply returns "this", this leads to error #2 above
me() {
this.chain( () => {
try {
return this
}
catch (e) {
const { message = "" } = e || {}
return Promise.reject({ message })
}
})
return this
}
The confusion on my part, is that if I use any value other than "this", it works as expected
me() {
this.chain( () => {
try {
return "test"
}
catch (e) {
const { message = "" } = e || {}
return Promise.reject({ message })
}
})
return this
}
x === "test"
I'm also able to return the values associated to this with something like the following
return {...this}
Ideally, I'd like to return the instance of Queue to X, as I plan on modifying the properties of the Queue instance through my async methods, await them, and be returned with an "initialized" instance of Queue.
Any input would be greatly appreciated - thank you!