DEV Community

Cover image for Top 10 Promise Way to Build and Level Up your Coding Skills
Shijie Zhou
Shijie Zhou

Posted on

Top 10 Promise Way to Build and Level Up your Coding Skills

There are many great ways to improve your coding skills, experiment with new technologies. The truth of the matter is to understand JavaScript and Promise.

Part 1:

const prom = new Promise((res, rej) => {
  console.log('first');
  res();
  console.log('second');
});
prom.then(() => {
  console.log('third');
});
console.log('fourth');

// first
// second
// fourth
// third
Enter fullscreen mode Exit fullscreen mode

Promise executes synchronously, promise.then executes asynchronously

Part 2:

const prom = new Promise((res, rej) => {
  setTimeout(() => {
    res('success');
  }, 1000);
});
const prom2 = prom.then(() => {
  throw new Error('error');
});

console.log('prom', prom);
console.log('prom2', prom2);

setTimeout(() => {
  console.log('prom', prom);
  console.log('prom2', prom2);
}, 2000);

// prom 
// Promise {<pending>}
// __proto__: Promise
// [[PromiseStatus]]: "resolved"
// [[PromiseValue]]: "success"

// prom2
// Promise {<pending>}__proto__: 
// Promise[[PromiseStatus]]: "rejected"[[PromiseValue]]: 
// Error: error
//     at <anonymous>:7:9
Enter fullscreen mode Exit fullscreen mode

promise has three different states:

  • pending
  • fulfilled
  • rejected

Once the status updated, pending->fulfilled or pending->rejected, it can be changed again. The prom1 is different from prom2 and both of them return new Promise status.

Part 3:

const prom = new Promise((res, rej) => {
  res('1');
  rej('error');
  res('2');
});

prom
  .then(res => {
    console.log('then: ', res);
  })
  .catch(err => {
    console.log('catch: ', err);
  });

// then: 1
Enter fullscreen mode Exit fullscreen mode

The resolve or reject only execute once even there is a resolve call after the reject. It won't execute.

Part 4:

Promise.resolve(1)
  .then(res => {
    console.log(res);
    return 2;
  })
  .catch(err => {
    return 3;
  })
  .then(res => {
    console.log(res);
  });

// 1
// 2
Enter fullscreen mode Exit fullscreen mode

Promises can be chained. When referring to chained calls, we usually think of returning this, but Promises do not. Each time a promise calls .then or .catch, a new promise will be returned, thus implementing chained calls.

Part 5:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('first')
    resolve('second')
  }, 1000)
})

const start = Date.now()
promise.then((res) => {
  console.log(res, Date.now() - start, "third")
})
promise.then((res) => {
  console.log(res, Date.now() - start, "fourth")
})

// first
// second 1054 third
// second 1054 fourth
Enter fullscreen mode Exit fullscreen mode

A promise .then or .catch can be called multiple times, but here the Promise constructor is executed only once. In other words, once the internal state of a promise changes and a value is obtained, each subsequent call to .then or .catch will directly get the value.

Part 6:

const promise = Promise.resolve()
  .then(() => {
    return promise
  })
promise.catch(console.error)

// [TypeError: Chaining cycle detected for promise #<Promise>]
// Uncaught SyntaxError: Identifier 'promise' has already been declared
//    at <anonymous>:1:1
// (anonymous) @ VM218:1
Enter fullscreen mode Exit fullscreen mode

The value returned by .then or .catch cannot be the promise itself, otherwise, it will cause an infinite loop.

Part 7:

Promise.resolve()
  .then(() => {
    return new Error('error');
  })
  .then(res => {
    console.log('then: ', res);
  })
  .catch(err => {
    console.log('catch: ', err);
  });

// then: Error: error!
// at Promise.resolve.then (...)
// at ...
Enter fullscreen mode Exit fullscreen mode

Returning an error object in .then or .catch does not throw an error, so it will not be caught by subsequent .catch, you need to change to one of them:

return Promise.reject(new Error('error'))
throw new Error('error')
Enter fullscreen mode Exit fullscreen mode

Because returning any non-promise value will be wrapped into a promise object, that is, return new Error ('error') is equivalent to return Promise.resolve (new Error ('error')).

Part 8:

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)

  // 1
Enter fullscreen mode Exit fullscreen mode

The argument of .then or .catch is expected to be a function, and passing in a non-function will results the result of value to be ignored such as .then(2) or .then(Promise.resolve(3).

Part 9:

Promise.resolve()
  .then(
    function success(res) {
      throw new Error('Error after success');
    },
    function fail1(e) {
      console.error('fail1: ', e);
    }
  )
  .catch(function fail2(e) {
    console.error('fail2: ', e);
  });

//   fail2:  Error: Error after success
//     at success (<anonymous>:4:13)
Enter fullscreen mode Exit fullscreen mode

.then can accept two parameters, the first is a function that handles success, and the second is a function that handles errors. .catch is a convenient way to write the second parameter of .then, but there is one thing to pay attention to in usage: .then the second error-handling function cannot catch the error thrown by the first successful function and subsequent ones. catch catches previous errors. Of course, the following code works if you want to rewrite:

Promise.resolve()
  .then(function success1 (res) {
    throw new Error('success1 error')
  }, function fail1 (e) {
    console.error('fail1: ', e)
  })
  .then(function success2 (res) {
  }, function fail2 (e) {
    console.error('fail2: ', e)
  })
Enter fullscreen mode Exit fullscreen mode

Part 10:

process.nextTick(() => {
  console.log('1')
})
Promise.resolve()
  .then(() => {
    console.log('2')
  })
setImmediate(() => {
  console.log('3')
})
console.log('4');

// Print 4
// Print 1
// Print 2
// Print 3
Enter fullscreen mode Exit fullscreen mode

Both process.nextTick and promise.then belong to microtask, while setImmediate belongs to macrotask, which is executed during the check phase of the event loop. A microtask is executed between each phase of the event loop (macrotask), and the beginning of the event loop is executed once.

Top comments (0)