Отмена Bluebird с ожиданием - PullRequest
2 голосов
/ 04 июня 2019

Этот код работает правильно:

let promise;
try {
    promise = parent();
    //but I want: await parent();
    await continueStack();
} catch (e) {
    console.log('Caught error in endpoint');
}

eventBus.on('stop::all', () => {
    console.warn('Caught stop::all event');
    promise.cancel();
});

Это отменяет обещание на событие, отправленное из другой части программы.Моя проблема в том, что у меня не может быть await parent(), потому что тогда прослушивание события еще не выполнено.Если я изменяю на это:

let promise;
eventBus.on('stop::all', () => {
    console.warn('Caught stop::all event');
    promise.cancel();
});

try {
    promise = await parent();
    await continueStack();
} catch (e) {
    console.log('Caught error in endpoint');
}

, тогда у меня появляется ошибка

TypeError: Невозможно прочитать свойство 'cancel' из неопределенного

, и происходит сбойи continueStack() никогда не выполняется.Как мне примирить их?


Я создал целый пример с приведенным выше сценарием:

https://gist.github.com/BorysTyminski/147dc2e0c44c8d64386253d563ff6db4

Чтобы запустить его, вам нужнополучите оба файла, установите package.json зависимости и запустите запрос cURL / Postman GET для localhost: 5000 / test

1 Ответ

1 голос
/ 04 июня 2019

Вы можете сделать это, установив promise var в parent, а затем ожидая его:

const EventEmitter = require('events');
const Promise = require('bluebird');

Promise.config({
  cancellation: true,
})
const parent = new Promise(resolve => {
  setTimeout( () => {
    resolve();
  }, 100);
});

const continueStack = new Promise(resolve => {
  setTimeout( () => {
    resolve();
  }, 100);
});

let promise;

const emitter = new EventEmitter();

emitter.on('stop', function() {
  if(promise && promise.cancel){
    promise.cancel();
    console.log('promise cancelled');
  } else {
    console.log('somehow promise was not properly set at this point');
  }
});

setTimeout(_ => {
  emitter.emit('stop');
}, 80);

async function operation() {
  try {
  promise = parent;
  await promise;
  console.log('after promise. This log should never appear.');
  await continueStack;
    console.log('after wait 2. This log should never appear.');
  } catch(e) {
    console.log('Even if the promise is cancelled, this is not called.');
  }
}

operation();

(выполнение этого фрагмента с узлом будет регистрировать только «обещание отменено»): ничего послеawait promise внутри асинхронной функции выполняется).

Некоторые соображения:

  • Promise.config необходим для установки cancellable в true.
  • await не похоже на сон.Он не блокирует поток JavaScript, ни прослушиватель событий, ни любой источник событий.Это просто гарантирует, что код, следующий за await, будет ожидать ожидаемого обещанного.Но это только в контексте асинхронной функции.

  • Отмена Promise не приводит к срабатыванию обработчика catch.Это озадачивает меня, но я полагаю, что так оно и есть.

...