Как использовать цепочку функций с асинхронной функцией? - PullRequest
2 голосов
/ 29 марта 2019

В настоящее время я пишу тест e2e, и я хотел бы создать несколько классов, которые абстрагируют меня от определенных асинхронных задач. В конце я хотел бы создать экземпляр объекта, который позволил мне связать асинхронные функции. Допустим, у меня есть Walker, который позволяет мне перемещаться по странице. Я хотел бы использовать это следующим образом:

const walker = new Walker(t)

await walker
  .goToMainPage()
  .goToProfile()

В настоящее время я могу использовать его только так:

const walker = new Walker(t)

await walker.goToMainPage()
await walker.goToProfile()

Это грубая реализация того, как я в настоящее время реализовал свой класс Уокера. Где t - это объект, который позволяет выполнять асинхронные действия в моем браузере.

class Walker {
  constructor(t) {
    this.t = t;
  }
  async goToMainPage () {
    await t.goTo('url/main')
    return this
  }
  async goToProfile () {
    await t.goTo('url/Profile')
    return this
  }
}

Есть идеи, как создавать асинхронные цепочки вызовов функций?

Ответы [ 2 ]

4 голосов
/ 29 марта 2019

await работает не только для Обещаний, но и для каждого объекта, который предоставляет обработчик .then ... поэтому ваш Walker может реализовать метод .then, позволяющий ожидать:

 class Walker {
   constructor(t) {
     this.t = t;
     // set up a task queue for chaining
     this.task = Promise.resolve();
    }

    // shedules a callback into the task queue
    doTask(cb) {
       // TODO: error handling
       return this.task = this.task.then(cb);
    }

    // allows to use this like a promise, e.g. "await walker";
    then(cb) { cb(this.task); }

    goToMainPage () {
      this.doTask(async () => { // shedule to chain
        await t.goTo('url/main')
      });
      return this; // return walker for chaining
   }

 }

Это позволяет вам:

 await walker.goToMainPage();
 await walker.goToMainPage().goToMainPage();

Если вы вернете что-то изнутри doTask, await, то это разрешится следующим образом:

 returnStuff() {
   this.doTask(() => "stuff");
   return this;
 }

 //...
 console.log(await walker.returnStuff()); // "stuff"
 console.log(await walker.returnStuff().goToMainPage()); // undefined, result gets lost

Веселитесь сэто!

2 голосов
/ 29 марта 2019

Вы используете async/await - по сути, это замена цепочки Promise (а Promises сами по себе являются решением для ада обратного вызова).Если вы действительно хотите использовать цепочку:

walker().then(w => w.goToMainPage()).then(w => w.goToProfile());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...