-1

I wanna create serial actions with promise and async/await. Code below. Instead of output: 1 2, I sometimes get 2 1. Does somebody know, how fix my gotcha? It is possible do with only promises? with generators? Also it can be, that onResolve() functions works asynchronously, so I need make them synchronous too.

Sequence:

request.get(payload, onResolve, onReject) // first get

.get(payload, onResolve, onReject) // second get

Run first get() do something with payload(_doSomething(payload)), after launch onResolve() or onReject depends on _doSomething() result, after onResolve() or onReject() launch second get() and same operations as in first get().

class Queue {
  constructor() {
    this.data = [];
  }

  add(record) {
    this.data.unshift(record);
  }

  remove() {
    return this.data.pop();
  }

  isEmpty() {
    return this.data.length === 0;
  }
}

class Request {
  constructor() {
    this._queue = new Queue();
    this._isPending = false;
  }

  _doSomething(payload) {
    setTimeout(() => {
      console.log(payload);
    }, Math.random() * 1000);
  }

  async _runCycle() {
    if (this._queue.isEmpty() || this._isPending) return;

    this._isPending = true;
    
    const { urlOne, onResolve, onReject } = this._queue.remove();
    await Promise.resolve(this._doSomething(urlOne))
      .then(() => onResolve())
      .catch(() => onReject());

    this._isPending = false;
    this._runCycle();
  }

  get(urlOne, onResolve, onReject) {
    
    this._queue.add({ urlOne, onResolve, onReject });
    this._runCycle();

    return this;
  }
}

const request = new Request();

request
  .get('1', ()=>1, ()=>0)
  .get('2', ()=>2, ()=>0);
Rami Chasygov
  • 2,714
  • 7
  • 25
  • 37

1 Answers1

1

you can use single Promise chain, but if your current code don't use Promise, please reconsider if it's necessary.


class Request {
  constructor() {
    this.resolver = Promise.resolve()
  }

  foo(x,time) {
    return new Promise((res,rej)=>
      setTimeout(() => {
        console.log(x);
        if(x==1)res();
        else rej();
      }, time));
  }

  get(x, time, res, rej) {
    let req = ()=>this.foo(x,time)
    this.resolver = this.resolver.then(req,req).then(res,rej)
    return this;
  }
}

const request = new Request();

request
  .get('1', 1000, ()=>console.log(11), ()=>console.log(10))
  .get('2', 200, ()=>console.log(21), ()=>console.log(20))
apple apple
  • 10,292
  • 2
  • 16
  • 36