有时我想推迟promise构造函数的执行,但仍然能够定义promise链。我发现并略微采用了以下方法,但是由于我对诺言的经验很少,所以我想知道


是否有更简洁的方法?
我用这种方法会失去什么?




class Deferred {
  constructor() {
    this.promise = new Promise((r, e) => {
      // arrows use this of their surrounding scope
      this.resolve = r;
      this.reject = e;
    });

    this.then = this.promise.then.bind(this.promise);
    this.catch = this.promise.catch.bind(this.promise);
    this.finally = this.promise.finally.bind(this.promise);
  }
}

const sqrAsync = n => {
  const d = new Deferred;

  d.runPromise = () => typeof n === "number"
    ? setTimeout(d.resolve, 0, n * n)
    : setTimeout(d.reject, 0, new Error("number expected"));

  return d;
};

const deferred = sqrAsync(5),
  deferred2 = sqrAsync("foo");

deferred
  .then(console.log)
  .catch(console.error)
  .finally(() => console.log("clean up 1st"));

deferred2
  .then(console.log)
  .catch(console.error)
  .finally(() => console.log("clean up 2nd"));

deferred.runPromise();
deferred2.runPromise();





我知道我可以使用userland的Task / Furture实现来实现此目标和其他期望的属性,通常我会这样做。但是,有时我需要ES6 Promise互操作。

预期原因:我想将“有效”的计算与程序的其余部分分开。

最佳答案

老实说,不要那样做。推迟递延是有充分理由的。

function sqrAsync(n) {
  return new Promise((resolve, reject) => {
    if (typeof n === "number")
      setTimeout(resolve, 0, n * n);
    else
      setTimeout(reject, 0, new Error("number expected"));
  });
}

var start1, start2;

const p1 = new Promise(resolve => { start1 = resolve; }).then(() => sqrAsync(5));
const p2 = new Promise(resolve => { start2 = resolve; }).then(() => sqrAsync("foo"));

p1.then(console.log, console.error).finally(() => console.log("clean up 1st"));
p1.then(console.log, console.error).finally(() => console.log("clean up 2nd"));

start1();
start2();


您永远不需要推迟Promise构造函数的执行。如果您需要在开始返回承诺的操作之前等待某事,请对某事做出承诺。

09-10 10:33
查看更多