1

Preface

Recently, I encountered a problem in development: there are four levels of linkage of drop-down components in the Table row, and new lines can be added, and each new line is four levels of linkage. Question: How to solve it? After thinking about it for a long time, I used Promise to solve it, which gave me a new understanding of Promise.

Promise detailed

Through the MDN official document there is an introduction to Promise: The Promise object is used to represent the final completion (or failure) of an asynchronous operation and its result value.

A Promise object represents a value that is not necessarily known when the promise is created. It allows you to associate the final success return value or failure reason of an asynchronous operation with the corresponding handler. This allows asynchronous methods to return values like synchronous methods: asynchronous methods do not return the final value immediately, but instead return a promise so that the value can be handed over to the user at some point in the future.

A Promise must be in one of the following states:

  • Pending: The initial state, neither being honored nor rejected.
  • Fulfilled: means the operation completed successfully.
  • Rejected (rejected): Means the operation failed.

A Promise object in a pending state will either be fulfilled with a value or rejected with a reason (error). When one of these situations occurs, the relevant handlers that we arranged with the then method of the promise will be called. If the promise is fulfilled or rejected when a corresponding handler is bound, then this handler will be called, so there will be no competition between completing the asynchronous operation and binding the processing method.

Because the Promise.prototype.then and Promise.prototype.catch methods return promises, they can be chained.

image.png
1. Constructor

Promise()
Create a new Promise object. This constructor is mainly used to wrap functions that have not yet added promise support.

2, static method

Promise.all(iterable)
This method returns a new promise object. The promise object will only trigger success when all the promise objects in the iterable parameter object succeed. Once any promise object in the iterable fails, it will trigger the failure of the promise object immediately. After this new promise object triggers the success state, an array containing all the promise return values in the iterable will be used as the return value of the success callback, the order is consistent with the order of the iterable; if this new promise object triggers the failure state, it The error message of the first promise object in the iterable that triggered the failure will be used as its failure error message. The Promise.all method is often used to handle the state collection of multiple promise objects. (You can refer to the jQuery.when method --- Translator's Note)

Promise.allSettled(iterable)
Wait until all promises have been settled (each promise has been fulfilled or rejected).
Return a promise that will be completed after all promises are completed. And with an array of objects, each object corresponds to the result of each promise.

Promise.any(iterable)
Receive a collection of Promise objects, and when one of the promises succeeds, return the value of that successful promise.

Promise.race(iterable)
When any child promise in the iterable parameter succeeds or fails, the parent promise will immediately use the success return value or failure details of the child promise as a parameter to call the corresponding handle bound to the parent promise and return the promise object.

Promise.reject(reason)
Return a Promise object with failed status, and pass the given failure information to the corresponding processing method

Promise.resolve(value)
Return a Promise object whose state is determined by the given value. If the value is thenable (that is, the object with the then method), the final state of the returned Promise object is determined by the execution of the then method; otherwise (the value is empty, the basic type or an object without the then method), it is returned The state of the Promise object is fulfilled, and the value is passed to the corresponding then method. Generally speaking, if you don't know whether a value is a Promise object, use Promise.resolve(value) to return a Promise object, so that you can use the value as a Promise object.

Use Promise

Through the above, you can learn more about the static method of Promise, and then use the Promise instance.

Create Promise

The Promise object is created by the keyword new and its constructor. The constructor takes a function called "executor function" as its parameter. This "processor function" accepts two functions-resolve and reject-as its parameters. When the asynchronous task is successfully completed and the result value is returned, the resolve function is called; when the asynchronous task fails and the reason for the failure is returned (usually an error object), the reject function is called.

const myFirstPromise = new Promise((resolve, reject) => {
  // ?做一些异步操作,最终会调用下面两者之一:
  //
  //   resolve(someValue); // fulfilled
  // ?或
  //   reject("failure reason"); // rejected
});

If you want a function to have a promise function, you only need to make it return a promise.

function myAsyncFunction(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onload = () => resolve(xhr.responseText);
    xhr.onerror = () => reject(xhr.statusText);
    xhr.send();
  });
};

Basic example

let myFirstPromise = new Promise(function(resolve, reject){
    //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
    //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
    setTimeout(function(){
        resolve("成功!"); //代码正常执行!
    }, 250);
});

myFirstPromise.then(function(successMessage){
    //successMessage的值是上面调用resolve(...)方法传入的值.
    //successMessage参数不一定非要是字符串类型,这里只是举个例子
    console.log("Yay! " + successMessage);
});

The base of

The Promise.all() method receives an input of a promise of iterable type (Note: Array, Map, and Set are all iterable types of ES6), and only returns a Promise instance, and the result of the resolve callback of all promises input is an array . The resolve callback of this Promise is executed when the resolve callbacks of all input promises have ended, or there is no promise in the input iterable. Its reject callback execution is that as long as the reject callback of any input promise is executed or an illegal promise is input, an error will be thrown immediately, and the reject is the first error message thrown.

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

Output:

> Array [3, 42, "foo"]

Promise daily use

In daily development situations, we will often deal with Promises. Here are the daily usage methods.

First define a Promise method,

api.js

function getData(){
    
    return new Promise(resolve => {
        
        axios.get('xxxx').then(res => {
            
            resolve(res.data)
        })
    }
}

Then the call in the component is divided into two ways to receive: 1, async await, 2, then, depending on which method you prefer to use.

async await method

async function query(){
    // res接收
    let res = await api.getData();
}

then

function query(){
    api.getData().then(res=>{
        // res接收
    });
}

Promise.all complex use

The following is a four-level linkage example to introduce the usage of Promise.all, which can be used in conjunction with the Array.map method, as shown below, the array contains selected values: one, two, three and four, and a list corresponding to the selected value: oneList , TwoList, threeList and fourList, and there is an association relationship between the four sets of data.

let arry = [{
    one: '',
    oneList: [],
    two: '',
    twoList: [],
    three: '',
    threeList: [],
    four: '',
    fourList: []
},{
    one: '',
    oneList: [],
    two: '',
    twoList: [],
    three: '',
    threeList: [],
    four: '',
    fourList: []
},{
    one: '',
    oneList: [],
    two: '',
    twoList: [],
    three: '',
    threeList: [],
    four: '',
    fourList: []
}]
// 获取所有oneList数据
Promise.all(arr.map(item => this.getOneList()))
   .then(promiseData => {
       //按顺序输出id对应的oneList 数据
       arr.forEach((item,index) => {
           item.oneList = promiseData[index]
       })
   })
// 获取所有twoList数据
Promise.all(arr.map(item => this.getTwoList(item.one)))
   .then(promiseData => {
       //按顺序输出id对应的twoList 数据
       arr.forEach((item,index) => {
           item.twoList = promiseData[index]
       })
   })
// 获取所有threeList数据
Promise.all(arr.map(item => this.getThreeList(item.two)))
   .then(promiseData => {
       //按顺序输出id对应的threeList 数据
       arr.forEach((item,index) => {
           item.threeList = promiseData[index]
       })
   })
// 获取所有fourList数据
Promise.all(arr.map(item => this.getFourList(item.three)))
   .then(promiseData => {
       //按顺序输出id对应的fourList 数据
       arr.forEach((item,index) => {
           item.fourList = promiseData[index]
       })
   })

In this way, the four-level list data can be obtained in batches and assigned to the arry array. At first, my solution was not like this. Instead, I used Promise in forEach and found that it didn’t work at all, because forEach itself is asynchronous, so I haven’t waited yet. The result is returned and it has been executed.

wrong usage

arry.forEach((item, index) => {
    item.oneList = this.getOneList();
    item.twoList = this.getTwoList(item.one);
    item.threeList = this.getThreeList(item.one);
    item.fourList = this.getFourList(item.one);
})

Although it's simple, it doesn't work in practice, so be careful.

Summarize:

1. forEach does not support Promise

Quote

JavaScript ES6 promise for loop duplicate
How to return many Promises and wait for them all before doing other stuff
Promise.all combined with async/await
Understand and use Promise.all and Promise.race
The asynchronous problem of


Awbeci
3.1k 声望212 粉丝

Awbeci


引用和评论

1 篇内容引用
0 条评论