The callback to hell in JS is an extremely painful thing. Promise can be a better solution, but it also has disadvantages. Let’s talk about its basic usage first.
If we do not use promise to write asynchronous operations, suppose we request three files:

1.txt;
2.txt;
3.txt

In JS, we will write as follows:

$.ajax({
                url('./upload/1.txt'),
                success(data) {
                    //do something
                    $.ajax({
                        url('./upload/2.txt'),
                        success(data) {
                            //do something
                            $.ajax({
                                url('./upload/3.txt'),
                                success(data) {
                                    //do something

                                },
                                error(err) {
                                    Alert ('error ')
                                }
                            })
                        },
                        error(err) {
                            Alert ('error ')
                        }
                    })
                },
                error(err) {
                    Alert ('error ')
                }
            })

It’s horrible, isn’t it
What promise solves is to write asynchronous operations in a synchronous way
There is a all method in promise, which puts the asynchronous operation we want to execute. After all operations are completed, the then method is called. This method has two parameters resolve and reject, and the operation is successful and the operation fails. Here’s an example:

Promise.all([
        $({url:'./upload/1.txt'}),
        $({url:'./upload/2.txt'}),
        $({url:'./upload/3.txt'})
    ]).then(resolve=>{
    //do something
    },reject=>{
        Alert ('error ')
    })

Resolve will be called only if all asynchronous operations succeed, otherwise reject will be called. This way of writing is much more comfortable.
The generator function is simply to pause the currently executing function to execute other code. When you want to continue to execute, you can continue to execute.
Create a generator function:

function *show(){
    //this is a generator function
}

Yes, it is a * sign in front of the function name. There is a yeld in it that is worth talking about.
After creating the generator function, we need to execute it. Unlike ordinary functions, the generator function is executed as follows:

function *show(){
 alert('do something');
 yeild;
 alert('continue');
}

let g1=show();
g1.next()//do something
alert('do other');//do other
g1.next()//continue

There is a yield in the function. This is where we call G1. Next() to execute. Then the program starts to execute alert (‘Do other ‘) from the first G1. Next(); after execution, we call G1. Next() to return to the show function and start to execute from yeld.
Among them, yeld can also pass parameters:

function *show(){
 alert('do something');
 yeild 5;
}
let a=g1.next();//a=5

Parameters can also be passed in:

function *show(){
 alert('do something');
 let a=yeild;
 alert(a)//6
}
g1.next();//do something
g1.next(6)