代码之家  ›  专栏  ›  技术社区  ›  JCarlosR

如何在不使用then方法的情况下定义承诺链

  •  8
  • JCarlosR  · 技术社区  · 6 年前

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

    首先,我写的是:

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

    并以此方式使用:

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

    我想 then 是非常重要的,因为它允许我们在承诺一得到解决就执行某件事。

    但我在找这样的东西:

    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 承诺从一开始,以链开始。但它仍然困扰着我。

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

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

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

    2 回复  |  直到 6 年前
        1
  •  7
  •   Felix Kling    6 年前

    如果您真的想创建一个可链接的接口,那么可以这样做:

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

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

        2
  •  6
  •   Andy Hoffman    6 年前

    你可以试试 async await

    const printIn1Sec = (value) => {
      return new Promise(resolve => {
        setTimeout(() => {
          console.log(value);
            resolve();
        }, 1000)
      });
    };
    
    async function fun(){
      await printIn1Sec(1);
      await printIn1Sec(2);
      await printIn1Sec(3);
    }
    
    fun();