admin管理员组

文章数量:1424923

I already looked for similar questions, but they are related to JQuery or any other library.

First, I wrote this:

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

And used it in this way:

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

I think then is very important, because it allows us to execute something as soon as the promise is resolved.

But I was looking for something like this:

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

I noticed I needed an object with access to this printIn1Sec method. So I defined a class:

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

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

And used it this way:

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

I had to resolve the Promise from the beginning, in order to the start the chain. But it still bothers me.

Do you think, is there a way to get it working like the following?

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

I was thinking in a new class or method, that could receive these values, store them, and finally start resolving the chain. But it would require to call an aditional method at the end, to init with the flow.

I already looked for similar questions, but they are related to JQuery or any other library.

First, I wrote this:

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

And used it in this way:

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

I think then is very important, because it allows us to execute something as soon as the promise is resolved.

But I was looking for something like this:

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

I noticed I needed an object with access to this printIn1Sec method. So I defined a class:

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

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

And used it this way:

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

I had to resolve the Promise from the beginning, in order to the start the chain. But it still bothers me.

Do you think, is there a way to get it working like the following?

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

I was thinking in a new class or method, that could receive these values, store them, and finally start resolving the chain. But it would require to call an aditional method at the end, to init with the flow.

Share Improve this question asked Jan 24, 2019 at 4:53 JCarlosRJCarlosR 1,6733 gold badges21 silver badges34 bronze badges 2
  • 4 Have you tried async/await? It is not going to be just like what you want but I remend you checking it if you hadn't. – holydragon Commented Jan 24, 2019 at 4:55
  • 1 While async/await is the obvious answer, I'm curious to see whether any trick exists that will (even clumsily) allow chaining in such a way. I doubt it but let's see. I'd remend the OP don't accept an answer immediately. – nicholaswmin Commented Jan 24, 2019 at 5:17
Add a ment  | 

2 Answers 2

Reset to default 7

If you really wanted to create a chainable interface as in your question, this would do it:

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

We just hide all the promise creation and chaining in an internal function. I split the code into smaller functions to make it a bit nicer looking.

You can try async and 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();

本文标签: javascriptHow to define a promise chain without using then methodStack Overflow