4

I have found a piece of code in this blog that works perfectly but makes a use of Promises that is hard to understand

export class Mutex {
  private mutex = Promise.resolve();

  lock(): PromiseLike<() => void> {
    let begin: (unlock: () => void) => void = unlock => {};

    this.mutex = this.mutex.then(() => {
      return new Promise(begin);
    });

    return new Promise(res => {
      begin = res;
    });
  }

  async dispatch(fn: (() => T) | (() => PromiseLike<T>)): Promise<T> {
    const unlock = await this.lock();
    try {
      return await Promise.resolve(fn());
    } finally {
      unlock();
    }
  }
}
  • Is valid the expression new Promise(res => { begin = res; })? Promises usually involve calling resolve on something

  • Why does const unlock = await this.lock(); resolve to a function?

Antonio Pérez
  • 6,702
  • 4
  • 36
  • 61
Jjm
  • 261
  • 2
  • 10
  • `res` is a bound method that can resolve (only that) Promise object. You can take *ownership* of the resolve function if you really want. See this answer of mine if you want to just play with resolve. https://stackoverflow.com/questions/57106667/syntax-of-promises-in-javascript-is-confusing/57106943#57106943 – Nishant Aug 07 '19 at 08:00
  • 1
    `let begin: (unlock: () => void) => void = unlock => {};` doesn't make any sense, that arrow function is never called but immediately overwritten in the `new Promise` executor. It really should be just `lock(): PromiseLike<() => void> { return new Promise(begin => { this.mutex = this.mutex.then(() => { return new Promise(begin); }); }); }` – Bergi Aug 07 '19 at 08:21

1 Answers1

3

Is it a valid expression? Promises usually involve calling resolve on something ...

Yes, it stores the resolve function in the global begin variable. Then when new Promise(begin) executes, it calls the begin function and thus resolves it.

Why does const unlock = await this.lock(); resolve to a function?

Because begin gets called by new Promise with the resolve function of that new Promise (begin(resolve, reject)). As begin is a resolver itself, it'll resolve the returned Promise to the resolver function of the other promise.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151