JavaScript

Last Updated: 4/13/2023

Promise

  • "Producing code" is code that can take some time
  • "Consuming code" is code that wants the result of the “producing code” once it’s ready.
  • A promise is a special JavaScript object that links the “producing code” and the “consuming code” together.
  • The function passed to new Promise is called the executor. When new Promise is created, the executor runs automatically. It contains the producing code which should eventually produce the result.
  • resolve and reject are callbacks provided by JavaScript itself.
  • resolve(value) — if the job is finished successfully, with result value.
  • reject(error) — if an error has occurred, error is the error object.
  • The promise state is initially "pending", then changes to either "fulfilled" when resolve is called or "rejected" when reject is called.
  • We can call .then on a Promise as many times as we want

Syntax

let promise = new Promise(function(resolve, reject) {
 // "Producing Code" (May take some time)
  resolve(); // when successful
  reject();  // when error
});

// "Consuming Code" (Must wait for a fulfilled Promise)
promise.then(
  function(value) { /* code if successful */ },
  function(error) { /* code if some error */ }
);

Using timer

const promise = new Promise(function(resolve, reject) {
     setTimeout(() => {
         resolve("done")
         //reject("fail");
     }, 3000);
 });

 promise.then(
     function(value) {
         console.log("success", value);
     },
     function(error) {
         console.log("failure", error);
     }
 )

Using then and catch

const promise = new Promise(function(resolve, reject) {
     setTimeout(() => {
         resolve("done")
         //reject("fail");
     }, 3000);
 });

promise
.finally(function(){
	console.log("promise ready");
})
.then(function(value) {
         console.log("success", value);
     }
 )
.catch(
     function(error) {
         console.log("failure", error);
	}
)

Loading script dynamically

function loadScript(url, callback) {
    return new Promise(function(resolve, reject){
        const script =  document.createElement("script");
        script.src = url
        document.head.append(script);

        script.onload = () => resolve(script);
        script.onerror = () => reject(new Error("loading failed"));
    })
}

const promise = loadScript("https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js");

promise.then(
    script => console.log(moment().format())
);

Multiple Handlers


const promise = loadScript("https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js");

promise.then(
    script => console.log(moment().format())
);

promise.then(
    script => console.log("script loaded")
)

Promise Chaining

Example 1

new Promise(function(resolve, reject) {
    setTimeout(() => resolve(1), 1000); // (*)
}).then(function(result) { // (**)
    console.log(result); // 1
    return result * 2;
}).then(function(result) { // (***)
    console.log(result); // 2
    return result * 2;
}).then(function(result) {
    console.log(result); // 4
    return result * 2;
});

Example 2

loadScript("script1.js")
.then(script => loadScript("script2.js"))
.then(script => loadScript("script3.js"))
.then(script => {
   // scripts are loaded, we can use functions declared there
});

Error handling with promises

  • Promise chains are great at error handling. When a promise rejects, the control jumps to the closest rejection handler.

Promises Methods

  • Promise.all(promises): waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, it becomes the error of Promise.all, and all other results are ignored.
  • Promise.allSettled(promises): (recently added method) – waits for all promises to settle and returns their results as an array of objects with: status: "fulfilled" or "rejected" value (if fulfilled) or reason (if rejected).
  • Promise.race(promises): waits for the first promise to settle, and its result/error becomes the outcome.
  • Promise.any(promises): (recently added method) – waits for the first promise to fulfill, and its result becomes the outcome. If all of the given promises are rejected, AggregateError becomes the error of Promise.any.
  • Promise.resolve(value): makes a resolved promise with the given value.
  • Promise.reject(error): makes a rejected promise with the given error.