Возможно ли Async Await - свободный подход - PullRequest
0 голосов
/ 08 марта 2019

Это мой путь взросления: обратные вызовы, обещания, асинхронность / ожидание.Я имею в виду модель - беглый строитель, который больше смотрит на переводчика.Я хотел бы смешать async / await с переводчиком.Является ли это возможным?Я чувствую, что это невозможно.Но я могу определить, почему именно.У меня есть:

  after(async () => {
    await shellContainer.uninstall()
    await shellContainer.dispose()
  })

Я интересуюсь:

after(async () => {
    await shellContainer
      .uninstall()
      .dispose()
  })

С уважением.

Ответы [ 3 ]

1 голос
/ 08 марта 2019

Чтобы разделить проблемы, вы можете представить выделенного построителя , который реализует свободный интерфейс.

С этим вам нужно только вернуть обещание из окончательного метода build, что делает вещинамного проще.

Ниже приведен довольно грубый, но функциональный пример:

class ShellContainer
{
  uninstall() {
    return new Promise(resolve => {
      setTimeout(() => {
        console.log('uninstalled');
        resolve();
      }, 400 + Math.random() * 600);
    });
  }

  dispose() {
    return new Promise(resolve => {
      setTimeout(() => {
        console.log('disposed');
        resolve();
      }, 400 + Math.random() * 600);
    });
  }
}

class ShellContainerBuilder
{
  container;
  plan;

  constructor() {
    this.reset();
  }

  reset() {
    this.container = new ShellContainer();
    this.plan = () => Promise.resolve();
  }

  stage(op) {
    this.plan = ((prev) => () => prev().then(op))(this.plan);
  }

  uninstall() {
    this.stage(() => this.container.uninstall());
    return this;
  }

  dispose() {
    this.stage(() => this.container.dispose());
    return this;
  }

  build() {
    return this.plan().then(() => this.container);
  }
}

(async () => {
  console.log('starting w/o builder:');
  const shellContainer1 = new ShellContainer();
  await shellContainer1.uninstall();
  await shellContainer1.dispose();
  console.log('w/o builder done.');

  console.log('starting w/ builder:');
  const shellContainer2 = await (new ShellContainerBuilder()).uninstall().dispose().build();
  console.log(shellContainer2);
  console.log('w/ builder done.');
})();
1 голос
/ 08 марта 2019

Если вы измените .uninstall, чтобы он возвращал экземпляр (shellContainer) при назначении его Promise свойству экземпляра и получении этого Promise в цепочечном вызове, да, это возможно:

class ShellContainer {
  uninstall() {
    // Chain or construct a Promise and assign the result to a property of the instance:
    this.uninstProm = new Promise((resolve, reject) => {
      // do stuff
    });
    return this;
  }
  dispose() {
    return this.uninstProm.then(() => {
      // do stuff
    });
  }
}

, а затем

await shellContainer
  .uninstall()
  .dispose()

разрешится после завершения dispose.

Обратите внимание, что при таком подходе вызов uninstall сам по себе может привести к неожиданному поведению, поскольку .uninsall будет возвращать экземпляр синхронно, а не Promise. Вы можете рассмотреть дополнительный аргумент или что-то еще, чтобы указать, хотите ли вы связать вызов uninstall с чем-то другим или хотите, чтобы обещание было возвращено напрямую, возможно, что-то вроде

class ShellContainer {
  uninstall(doChain) {
    // Chain or construct a Promise and assign the result to a property of the instance:
    this.uninstProm = new Promise((resolve, reject) => {
      // do stuff
    });
    return doChain ? this : this.uninstProm;
  }
  dispose() {
    return this.uninstProm.then(() => {
      // do stuff
    });
  }
}

и

  await shellContainer
    .uninstall(true)
    .dispose()

или просто

await shellContainer.uninstall(); // no doChain argument

Но если будет только one Promise, во многих случаях await не так много необходимости - это может вообще не сделать код более понятным. Например

after(async () => {
  await shellContainer
    .uninstall()
    .dispose()
})

эквивалентно

after(() => shellContainer
              .uninstall()
              .dispose()
);
0 голосов
/ 08 марта 2019

Шаблон - интерпретатор, который реализует Fluent Builder, не подходит для Async / Await. Потому что ожидание применяется за операцию. Нет такого синтаксиса для обработки асинхронного в середине цепочки. Для обработки асинхронных операций вы должны разделить цепочку и обернуть операции с помощью оператора ожидания, как в первом фрагменте кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...