2

ES6 Promise Object-Write asynchronous code like synchronous code

blog description

The information involved in the article comes from the Internet and personal summary, which is intended to summarize personal learning and experience. If there is any infringement, please contact me to delete it, thank you!

Introduction

Syntactically speaking, a Promise is an object, from which you can obtain messages for asynchronous operations. Promise provides a unified API, and various asynchronous operations can be processed in the same way. In layman's terms, Promise is a container that holds the results of asynchronous operations.

Features

The state of the object is not affected by outside

Promise object has three states: pending (in progress), fulfilled (successful), and rejected (failed).

Only the result of an asynchronous operation can determine which state is currently in, and no other operation can change this state.

Once the state changes, it won’t change again, you can get this result at any time

Promise are only two possibilities for the state of the pending to fulfilled and from pending to rejected . As long as these two situations occur, the state will be frozen and will not change anymore, and this result will always be maintained. At this time, it is called resolved (finalized).

Advantages and disadvantages

advantage

1. The Promise object can express asynchronous operations as a synchronous operation process, and write asynchronous codes in a synchronous manner, avoiding layers of nested callback functions.

2. The Promise object provides a unified interface, which makes it easier to control asynchronous operations.

Disadvantage

Promise cannot be cancelled. Once it is created, it will be executed immediately and cannot be cancelled halfway.

2. If the callback function is not set, Promise will not be reflected to the outside.

3. Third, when in the pending , it is impossible to know which stage it is currently progressing (just started or is about to be completed).

Case study

Promise instance

Promise constructor accepts a function as a parameter. The two parameters of the function are resolve and reject . Note that these two are two functions.

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

resolve function of the Promise the status of the 060ed39fbae68b object from "unfinished" to "success" (that is, from pending to resolved), and it is called when the asynchronous operation is successful, and the result of the asynchronous operation is passed as a parameter;

reject function of the Promise the status of the 060ed39fbae6b0 object from "unfinished" to "failed" (that is, from pending to rejected), which is called when the asynchronous operation fails, and the error reported by the asynchronous operation is passed as a parameter .

Promise execution order

Promise will be executed immediately after it is created.

let promise = new Promise(function(resolve, reject) {
  console.log('11');
  resolve();
});

promise.then(function() {
  console.log('22');
});

console.log('33');

// 11
// 33
// 22

Promise is executed immediately after creation, so the first output is 11 . then method is an asynchronous function, and will be executed after all the synchronous tasks of the current script are executed, so the output is 33 and 22 last output.

Asynchronous loading picture case

Use Promise wrap an asynchronous operation of image loading. If the loading is successful, call the resolve method, otherwise call the reject method.

function loadImageAsync(url) {
  return new Promise(function(resolve, reject) {
    const image = new Image();

    image.onload = function() {
      resolve(image);
    };

    image.onerror = function() {
      reject(new Error('Could not load image at ' + url));
    };

    image.src = url;
  });
}
Ajax implemented by Promise objects

The XMLHttpRequest object is encapsulated in the getTest function, an HTTP request is sent, and a Promise object is obtained.

const getTest = function(url) {
  const promise = new Promise(function(resolve, reject){
    const handler = function() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

  });

  return promise;
};


// 调用案例
getTest("/test.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error(error);
});

Promise error handling

If the Promise status has changed to resolved , throwing an error again is invalid. Because once the state of the Promise changes, it will remain in that state forever and won't change anymore.

The error of the Promise object has a bubbling and will be passed backwards until it is caught. In other words, the error will always be caught by the next catch statement.

const promise = new Promise(function(resolve, reject) {
  resolve('ok');
  throw new Error('test');
});
promise
  .then(function(value) { console.log(value) })
  .catch(function(error) { console.log(error) });
// ok

thanks

Universal network

Ruan Yifeng's es6 grammar tutorial

And hard-working self, personal blog , GitHub

微信公众号


归子莫
1k 声望1.2k 粉丝

信息安全工程师,现职前端工程师的全栈开发,三年全栈经验。