Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a promise chain without using then method

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.

like image 379
JCarlosR Avatar asked Jan 24 '19 04:01

JCarlosR


People also ask

Does promise run without then?

The code inside the Promise constructor runs when the promise is created and it runs synchronously which surprises some people. So even without then() everything still runs.

What type of method is used in promise chaining?

A Promise is executed by using the . then() method written after the declared promise. If we need to handle any error which is occurred then we use the . catch() method written after promise.

Why do we use then in promise?

The then() method in JavaScript has been defined in the Promise API and is used to deal with asynchronous tasks such as an API call. Previously, callback functions were used instead of this function which made the code difficult to maintain.

What is promise resolve () then?

The Promise.resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise.resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.


2 Answers

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.

like image 156
Felix Kling Avatar answered Nov 15 '22 00:11

Felix Kling


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();
like image 31
Surojit Paul Avatar answered Nov 14 '22 23:11

Surojit Paul