首页 > 解决方案 > 如何在不使用 then 方法的情况下定义承诺链

问题描述

我已经寻找过类似的问题,但它们与 JQuery 或任何其他库有关。

首先,我写了这个:

const printIn1Sec = (value) => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(value);
      resolve();
    }, 1000)
  });
};

并以这种方式使用它:

printIn1Sec(1)
.then(() => printIn1Sec(2))
.then(() => printIn1Sec(3));

我认为then这很重要,因为它允许我们在 promise 解决后立即执行某些操作。

但我一直在寻找这样的东西:

printIn1Sec(1)
.printIn1Sec(2)
.printIn1Sec(3);

我注意到我需要一个可以访问此printIn1Sec方法的对象。所以我定义了一个类:

class Printer extends Promise {
  in1Sec(v) {
    return this.then(() => this.getPromise(v));
  }

  getPromise(value) {
    return new Printer(resolve => {
      setTimeout(() => {
        console.log(value);
        resolve();
      }, 1000)
    })
  }
}

并以这种方式使用它:

Printer.resolve().in1Sec(1).in1Sec(2).in1Sec(3);

我必须resolve从一开始就遵守 Promise,才能启动链条。但它仍然困扰着我。

你认为,有没有办法让它像下面这样工作?

printIn1Sec(1).printIn1Sec(2).printIn1Sec(3);

我正在考虑一个新的类或方法,它可以接收这些值,存储它们,最后开始解析链。但它需要在最后调用一个附加方法来初始化流程。

标签: javascriptecmascript-6es6-promise

解决方案


如果您真的想在问题中创建一个可链接的接口,可以这样做:

const printIn1Sec = (function() {

  function setTimeoutPromise(timeout) {
    return new Promise(resolve => setTimeout(resolve, 1000));
  }

  function printIn1Sec(value, promise) {
    const newPromise = promise
      .then(() => setTimeoutPromise(1000))
      .then(() => console.log(value));

    return {
      printIn1Sec(value) {
        return printIn1Sec(value, newPromise);
      },
    };
  }

  return value => printIn1Sec(value, Promise.resolve());
}());

printIn1Sec(1)
  .printIn1Sec(2)
  .printIn1Sec(3);

我们只是将所有的 Promise 创建和链接隐藏在一个内部函数中。我将代码拆分为更小的函数,以使其看起来更好看。


推荐阅读