【问题标题】:how to cancel promises with bluebird如何用蓝鸟取消承诺
【发布时间】:2018-10-23 22:23:13
【问题描述】:

我想我误解了 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(); 
      });
  });
});

【问题讨论】:

  • p1 怎么可能被取消?它已经在p1 = Promise.resolve(1) 行中实现了。
  • @Bergi 感谢您指出,今天不是我最好的一天 xD。我已经更新了sn-p,你能再看一下吗?谢谢。

标签: promise bluebird cancellation


【解决方案1】:

来自here

取消功能默认关闭,您可以使用 Promise.config 启用它。

似乎您没有在 Promise 本身上启用 cancellation 标志:

Promise.config({
  cancellation: true
});

describe(...

【讨论】:

  • 请注意它是开启的,见expect(p2.isCancellable()).toBeTruthy();
【解决方案2】:

@Karen 如果正确。但问题是你的测试也有点错误

如果你看isCancellable方法

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

这只是检查promise 是否为pending 并且尚未取消。这并不意味着取消是启用的。

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

如果你看到上面的网址,它会在下面引用

取消功能默认关闭,您可以使用 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(); 
    });
  });

您可以看到取消未启用并执行警告代码

执行结果按预期失败

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(); 
    });
  });

有效!

【讨论】:

  • 感谢您的深入回答。我发现对我来说潜在的问题是使用 async / await 这似乎与 bluebird 不兼容
  • 更具体地说——如果您将awaitAndAddOne 更改为async,则p2._cancellationParent === p1 为假。如果你保持它没有异步,它将评估为 true,并且由于取消工作正常。
猜你喜欢
  • 2015-02-13
  • 2019-09-29
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 2017-06-18
  • 2014-07-31
  • 1970-01-01
  • 2014-02-13
相关资源
最近更新 更多