как отменить обещания с синей птицей - PullRequest
0 голосов
/ 14 мая 2018

Мне кажется, я неправильно понимаю, как работает отмена обещаний с помощью bluebird.Я написал тест, который демонстрирует это.Как мне сделать это зеленым?Спасибо:

describe('cancellation tests', () => {
  function fakeFetch() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(1);
      }, 100);
    });
  }

  function awaitAndAddOne(p1) {
    return p1.then(res => res + 1);
  }

  it('`cancel` cancels promises higher up the chain', () => {
    const p1 = fakeFetch();
    const p2 = awaitAndAddOne(p1);

    expect(p2.isCancellable()).toBeTruthy();
    p2.cancel();

    return p2
      .then(() => {
        console.error('then');
      })
      .catch(err => {
        console.error(err);
      })
      .finally(() => {
        expect(p2.isCancelled()).toBeTruthy(); // Expected value to be truthy, instead received false
        expect(p1.isCancelled()).toBeTruthy(); 
      });
  });
});

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

@ Карен, если правильно.Но проблема в том, что ваш тест также немного неправильный

Если вы посмотрите на метод isCancellable

Promise.prototype.isCancellable = function() {
    return this.isPending() && !this.isCancelled();
};

Это просто проверка, является ли promise pending иеще не отмененоЭто не значит, что отмена включена.

http://bluebirdjs.com/docs/api/cancellation.html

Если вы видите вышеупомянутый URL, он цитируется ниже

Функция отмены по умолчанию отключена , выможно включить его с помощью Promise.config.

И если вы посмотрите на метод cancel

Promise.prototype["break"] = Promise.prototype.cancel = function() {
    if (!debug.cancellation()) return this._warn("cancellation is disabled");

Теперь, если я обновлю ваш тест, исправьте, как показано ниже

var Promise = require("bluebird");
var expect = require("expect");

describe('cancellation tests', () => {
    function fakeFetch() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(1);
        }, 100);
      });
    }

    function awaitAndAddOne(p1) {
      return p1.then(res => res + 1);
    }

    it('`cancel` cancels promises higher up the chain', () => {
      const p1 = fakeFetch();
      const p2 = awaitAndAddOne(p1);

      value = p2.isCancellable();
      expect(p2.isCancellable()).toBeTruthy();
      p2.cancel();

      expect(p2.isCancelled()).toBeTruthy(); // Expected value to be truthy, instead received false
      expect(p1.isCancelled()).toBeTruthy(); 
    });
  });

Вы можете видеть, что отмена не включена и выполняет код предупреждения

Cancellation is disabled

Результаты выполнения не соответствуют ожидаемым

spec.js:46
  cancellation tests
spec.js:46
    1) `cancel` cancels promises higher up the chain
spec.js:78
  0 passing (3m)
base.js:354
  1 failing
base.js:370
  1) cancellation tests
base.js:257
       `cancel` cancels promises higher up the chain:
     Error: expect(received).toBeTruthy()
Expected value to be truthy, instead received
  false
      at Context.it (test/index.test.js:37:36)

Теперь, если вы обновите код для разрешения отмены

var Promise = require("bluebird");
var expect = require("expect");

Promise.config({
  cancellation: true
});

describe('cancellation tests', () => {
    function fakeFetch() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(1);
        }, 100);
      });
    }

    function awaitAndAddOne(p1) {
      return p1.then(res => res + 1);
    }

    it('`cancel` cancels promises higher up the chain', () => {
      const p1 = fakeFetch();
      const p2 = awaitAndAddOne(p1);

      value = p2.isCancellable();
      expect(p2.isCancellable()).toBeTruthy();
      p2.cancel();

      expect(p2.isCancelled()).toBeTruthy(); // Expected value to be truthy, instead received false
      expect(p1.isCancelled()).toBeTruthy(); 
    });
  });

Это работает!

Cancellation works

0 голосов
/ 15 мая 2018

С здесь :

Функция отмены по умолчанию отключена, вы можете включить ее с помощью Promise.config.

Похоже, вы не включили флаг cancellation на самом Promise:

Promise.config({
  cancellation: true
});

describe(...
...