Promise

Promise to introduce

The Promise object represents the final completion (or failure) of an asynchronous operation and its resulting value.

Status:

A promise must be in one of the following states

  • Pending: Initial state (Pending)
  • This is a pity. The operation will be completed successfully.
  • Rejected: Operation failed (REJECT)

Create a Promise

The Promise object is created by the keyword new and its constructor. The constructor takes a function called “executor Function” as its argument. This “processor function” takes two functions, resolve and reject, as its arguments. The resolve function is called when the asynchronous task completes successfully and the result value is returned. The Reject function is called when the asynchronous task fails and returns the cause of the failure (usually an error object).

new Promise((resolve, reject) = > {
  // The processing operation returns resolve or reject
  if (flag) resolve(data);
  eles(reject(data));
});
Copy the code

You need some custom function to become a Promise by simply returning a Promise

function myFun(flag) {
  return new Promise((resolve, reject) = > {
    // The processing operation returns resolve or reject
    if (flag) resolve(data);
    eles(reject(errorData));
  });
}
Copy the code

In a specific project, use the Promise wrapper to get the current configuration method.

/** * get dictionary list ** axios: axios * lang: current language, according to different languages, get different configurations ** determine whether sessionStorage has obtained the current dictionary configuration. * If this configuration is returned, no more data is obtained from the interface and saved to sessionStorage. * /
function getDictionary(axios, lang) {
  / / check the sessionStorage
  const dic = sessionStorage.getItem("dictionary_data_" + lang) || null;
  // Return a Promise object
  return new Promise((resolve, reject) = > {
    if (dic) resolve(JSON.parse(dic));
    else {
      axios
        .get(`/api/dictionary? language=${lang}`)
        .then((res) = > {
          const dic_data = {};
          if (res.data.code === 0 && res.data.result) {
            res.data.result.forEach((r) = > (dic_data[r.itemName] = r));
            / / store sessionStorage
            sessionStorage.setItem(
              "dictionary_data_" + lang,
              JSON.stringify(dic_data)
            );
            // Return data
            resolve(dic_data);
          } else reject();
        })
        .catch((error) = >reject()); }}); }Copy the code

A static method

Primise.all(iterable)

The pass parameter needs to be an iterable Promise. All returns a Promise object. The Promise object will not fire until all of the Promise objects in the iterable parameter promise. all succeed.

In simple terms, only all promises in the promise. all parameter will be triggered if they succeed, and none if they fail.

Such as:

var promise1 = Promise.resolve("heihei");
var promise2 = "wenbo";
var promise3 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve([1.2.3]);
  }, 2000);
});

Promise.all([promise1, promise2, promise3]).then((res) = > {
  console.log(res);
});
Copy the code

The code above prints [‘heihei’, ‘WENbo ‘, [1, 2, 3]] after about two seconds because promise. all waits for setTimeout in promise3 to complete before triggering the return of the Promise object

Another example:

var promise1 = Promise.reject("heihei");
var promise2 = "wenbo";
var promise3 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve([1.2.3]);
  }, 2000);
});

Promise.all([promise1, promise2, promise3])
  .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e);
  });
Copy the code

[‘heihei’, ‘wenbo’, [1, 2, 3]] instead of waiting 2 seconds to print heihei [‘heihei’, ‘WENbo ‘, [1, 2, 3]] Promise1 = promise1 = promise1 = promise1 = promise1 Promise.all asynchronously returns failed results, regardless of whether other promises have been fulfilled.

In certain cases, the data returned by promise.all is required to continue executing the code. Because promise. all is asynchronous, we can implement it with async and await.

var promise1 = Promise.resolve("heihei");
var promise2 = "wenbo";
var promise3 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve([1.2.3]);
  }, 2000);
});

function demo() {
  Promise.all([promise1, promise2, promise3]).then((res) = > {
    console.log(res);
  });
  console.log("heihei");
}
demo();
Copy the code

[‘heihei’, ‘WENbo ‘, [1, 2, 3]]

var promise1 = Promise.resolve("heihei");
var promise2 = "wenbo";
var promise3 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve([1.2.3]);
  }, 2000);
});

async function demo() {
  await Promise.all([promise1, promise2, promise3]).then((res) = > {
    console.log(res);
  });
  console.log("heihei");
}
demo();
Copy the code

After async and await is used, heihei will be printed after promise. all is executed. In a real project, you can use the data returned by promise.all below.

Promise.allSettled(iterable)

The pass parameter needs to be an iterable Promise. AllSettled returns a Promise object. The Promise object will not fire until all the Promise objects in the Promise.allSettled Iterable parameter object succeed or fail.

Simply put, the Promise will not be triggered until all the promises have been fulfilled, whether they succeed or fail.

var promise1 = Promise.reject("heihei");
var promise2 = "wenbo";
var promise3 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve([1.2.3]);
  }, 2000);
});

Promise.allSettled([promise1, promise2, promise3])
  .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e);
  });
Copy the code

The output is:

[{status: "rejected".reason: "heihei" },
  { status: "fulfilled".value: "wenbo" },
  { status: "fulfilled".value: [1.2.3]]},Copy the code

Promise.allsettled returns an array containing the state status of each Promise, the return value Value, and the value Reason of Rejected

Promise.all() is better suited to relying on each other or ending immediately in any of them than promise.all ().

Promise.any(iterable)

The pass parameter needs to be an iterable Promise. Any returns a Promise object. Receives a collection of Promise objects, and when one Promise succeeds, returns the value of that successful Promise.

var promise1 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve([4000]);
  }, 4000);
});
var promise2 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve([1000]);
  }, 1000);
});

Promise.any([promise1, promise2])
  .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e);
  });
Copy the code

In simple terms, promises.any is like racing. Whichever Promise succeeds first is returned

Promise.any and promise. all are opposites, one is triggered by all success, the other is triggered by one success.

var promise1 = Promise.reject("error");
var promise2 = Promise.reject("error2");
Promise.any([promise1, promise2])
  .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e);
  });

/ / output

//AggregateError: All promises were rejected
Copy the code

As shown in the code above, an Error Promise is returned when all promises fail

Promise.race(iterable)

The pass parameter needs to be an iterable Promise. Any returns a Promise object. Receives a collection of Promise objects, and when one of the promises succeeds or fails, returns the value of that successful or failed Promise.

In contrast, promise. any returns a successful Promise if there is a success, and promise. race returns either success or failure

var promise1 = Promise.resolve("resolve");
var promise2 = Promise.reject("error");
Promise.race([promise1, promise2])
  .then((res) = > {
    console.log(res); //resolve
  })
  .catch((e) = > {
    console.log(e);
  });
// The output is resolve
var promise1 = Promise.reject("error");
var promise2 = Promise.resolve("resolve");

Promise.race([promise1, promise2])
  .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e); //error
  });

// The output is error
Copy the code

Promise.reject(reason)

The promise.reject () method returns a Promise object with a failed state and passes the given failure information to the corresponding handler.

Promise.reject("test-reject")
  .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e); //test-reject
  });
Copy the code

Promise.resolve(value)

Returns a Promise object whose state is determined by the given value

If this is a Promise object, return the Promise object. If the value is thenable (that is, with the “then” method), the returned promise will “follow “the thenable object and adopt its final state

Promise.resolve("test-resolve")
  .then((res) = > {
    console.log(res); //test-resolve
  })
  .catch((e) = > {
    console.log(e);
  });
Copy the code

When Resolve is a Promise object, the Promise object is returned.

var promise = Promise.resolve({
  name: "resolve"});Promise.resolve(promise)
  .then((res) = > {
    console.log(res); //{name:resolve}
  })
  .catch((e) = > {
    console.log(e);
  });
/ / reject
var promise = Promise.reject({
  name: "reject"});Promise.resolve(promise)
  .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e); //{name:reject}
  });
Copy the code

When Resolve is a Thenable object

var p1 = Promise.resolve({
  then: function (resolve, reject) {
    resolve("hello ~!"); }}); p1.then((res) = > {
  console.log(res); //hello ~!
});
Copy the code

Note: Call promise.resolve on thenable that resolves to itself. This leads to infinite recursion.

Promise prototype approach

Promise.prototype.catch(onRejected)

The catch() method returns a Promise, And handling the rejection actually acts as a catch with calling promise.prototype. then(undefined, Obj. Catch (onRejected) internal calls obj. Then (undefined, onRejected)

var promise = new Promise((resolve, reject) = > {
  throw "An error has occurred.";
});
promise.then(
  (res) = > {
    console.log(res);
  },
  (e) = > {
    console.log(e); // An error occurred ~}); promise .then((res) = > {
    console.log(res);
  })
  .catch((e) = > {
    console.log(e); // An error occurred ~
  });
Copy the code

Both methods can be used to catch exceptions

Promise.prototype.then(onFulfilled, onRejected)

The then() method returns a Promise. It needs at most two arguments: a callback to Promise’s success and failure cases.

The default is the Promise’s successful callback function when wearing only one value

// A default argument
var promise = new Promise((resolve, reject) = > {
  resolve("Success!");
  //or
  // reject(' reject ~')
});

promise.then(
  (res) = > {
    console.log(res); ~ / / success
  },
  (error) = > {
    console.log(error); ~ / / failure});Copy the code

Promise.prototype.finally(onFinally)

The finally() method returns a Promise. At the end of the promise, the specified callback function will be executed, whether the result is fulfilled or Rejected. This provides a way for code to be executed after a Promise is successfully completed or not. This avoids the need to write the same statement once in both then() and catch().

var promise = new Promise((resolve, reject) = > {
  resolve("Success!");
  //or
  // reject(' reject ~')
});

promise
  .then(
    (res) = > {
      console.log(res); ~ / / success
    },
    (error) = > {
      console.log(error); ~ / / failure
    }
  )
  .finally((res) = > {
    console.log("finally~");
  });
Copy the code

As shown in the code above, the contents of finally are executed whether a Promise returns resolve or reject.

The chain using

Since promise.then(), promise.catch(), and promise.finally() can operate on completed (successful or failed) promises and return a new promise object, We can also use these methods to operate on the new Promise object, forming a chain operation.

var promise = new Promise((resolve, reject) = > {
  resolve("Success!");
});

promise
  .then((res) = > {
    console.log(res); / / success
    return new Promise((resolve, reject) = > {
      resolve("Successful 01 ~");
    });
  })
  .then((res) = > {
    console.log(res); 01 ~ / / success
    return new Promise((resolve, reject) = > {
      resolve("Successful 02 ~");
    });
  })
  .then((res) = > {
    console.log(res); 02 ~ / / success
    throw "error~";
  })
  .catch((e) = > {
    console.log(e); //error~
  });
Copy the code