You might unleash a monster

One of the most difficult things to control in asynchronous versus synchronous is when the asynchronous task will complete and the callback after completion.

The unmanageable trigger state allows your code to be readable at the time, but you never know what will be executed first if you don’t rework the logic a few days or two weeks later

listen( "click".function handler(evt){
	setTimeout( function request(){
		ajax( "http://some.url.1".function response(text){
			if (text == "hello") {
				handler();
			}
			else if (text == "world") { request(); }}); },500); }); doSomething();Copy the code

It’s hard to understand how much this hellish callback (callback hell) destroys readability.

First execute listern ()

Second doSomething ()

Ajax execution after 500ms (or more)

Ajax is completed

If text === hello executes handler ()

If text === world executes request ()

Does it hurt??

In the javascript you Don’t Know book, the issue of trust in callbacks is addressed. When you use third-party library methods to handle callbacks, you are likely to encounter the following trust:

How to solve ???? What about this trust issue?

It turns out you need a commitment

When you give others to do one thing can be done (may soon may also be a need for a period of time) the person after the task is complete or failure will give you a response, such people are you special trust to get things to him, he didn’t respond to you so he is eps, response to you is the success or failure.

In javascript, that person is a Promise.

An instance of Promise has three states: Pending, Resolved, and Rejected. When you give something to a Promise, its state is “Pending”. When the task is completed, it becomes “Resolved” and when it fails, it becomes “Rejected”.

Without further ado: Write a simple promise

let promise = new Promise((resolve,reject) = >{
    // Receive a callback. The arguments are success and failure functions
	setTimeout((a)= >{
       let num = parseInt(Math.random()*100);
       // Call the successful function if the number is greater than 50 and change the state to Resolved
       if(num > 50){
          resolve(num);
       }else{
        // Otherwise call the failed function and change the state to Rejected
          reject(num)
       }
	},10000)})Copy the code

When a Promise executes something that you expect to succeed, you call resolve and reject, and the arguments for both are captured by the Promise. This can be used in later callbacks.

Now that we’re done creating a promise, how do we use the results of the promise?

promise.then(res= >{
    console.log(res);
    // In the constructor you get to this point if you execute the resolve function
},err=>{
    // Reject is rejected
    console.log(err);
})
Copy the code

The then method receives two functions, the first is a callback that promises success (in the resolved state) and a callback that promises failure (in the rejected state).

The return value of the THEN method is wrapped as a Promise object if it is not a Promise object, so the THEN method supports chained calls.

promise.then(res= >{ return 42}).then(res= >{console.log(res)})
// Print out 42
Copy the code

The chain calls to the then method can help us solve some of the logic serialized when we normally write sequential asynchronous times, such as

ajax('first');
ajax('second');
ajax('third'); What if I need to do it sequentially? ajax('first').success(function(res){
    ajax('second').success(function(res){
        ajax('third').success(function(res){
            // Now you can execute what you want}); })}) What a beautiful and daunting triangle!!Copy the code

What if you use a chained call to THEN?

let promise = new Promise((resolve,reject) = >{
    ajax('first').success(function(res){
        resolve(res);
    })
})
promise.then(res= >{
    return new Promise((resovle,reject) = >{
        ajax('second').success(function(res){
            resolve(res)
        })
    })
}).then(res= >{
    return new Promise((resovle,reject) = >{
        ajax('second').success(function(res){
            resolve(res)
        })
    })
}).then(res= >{
    // Serial complete you want to do XXX can begin
})
Copy the code

And every time you execute resolve, you can pass each Ajax callback to the end. Be clear and simple.

Say serial, then how to do parallel?? When you have multiple asynchronous events, unrelated and in no order, you just need to complete all of them and start working.

Serial adds up the wait times for each asynchronous event, apparently blocking completion. So in parallel, how do we make sure we’re all done?

Promise. All and Promise. Race

Promise.all receives an array, each of which is a Promise object. When all the promise states in the array reach Resolved, the promise. all state will change to Resolved. If one of the states changes to Rejected, the promise. all state will change to Rejected. This will solve our parallelism problem. The result of a successful call to then is also an array of arguments that hold the values of each promise object, resolve, in order.

let promise1 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       resolve(1);
	},10000)});let promise2 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       resolve(2);
	},9000)});let promise3 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       resolve(3);
	},11000)});Promise.all([promise1,promise2,promise3]).then(res= >{
    console.log(res);
    // the [1,2,3] proof is independent of which promise state becomes resolved first
})

let promise1 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       reject(1);
	},10000)});let promise2 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       resolve(2);
	},9000)});let promise3 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       resolve(3);
	},11000)});let promiseAll =Promise.all([promise1,promise2,promise3]);
promiseAll.then(res= >{
    console.log(res);
},err=>{
    console.log(err)
})
Copy the code

The promise. race pattern also accepts an array of promises for each item. But different from all, when the first promise object becomes resolved, its state becomes resolved, and when the first promise becomes Rejected, its state becomes Rejected. The first promsie value that becomes Resolved will be used.

let promise1 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       reject(1);
	},10000)});let promise2 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       resolve(2);
	},9000)});let promise3 = new Promise((resolve,reject) = >{
	setTimeout((a)= >{
       resolve(3);
	},11000)});Promise.race([promise1,promise2,promise3]).then(res= >{
	console.log(res);
	// Print 2. Why not print 1? Because promise2 does it first and ignores the rest
},rej=>{
    console.log('rejected');
    console.log(rej)};
)
// You can try changing the time to test yourself
Copy the code

Another important practical use of promsie.race is that what happens when we’re going to do something and we stop after about three seconds? Use the promise.race method at this point

Promise.race([promise1,timeOutPromise(3000)]).then(res= >{})
3s (generally, the main thread will not block above 3s in development, so it will not be a big problem)
Copy the code

That’s my basic understanding of promises.

A very uncomfortable thing is that I deleted the 1736 words I had written hard during the day. Where did the content go?? It’s blue and thin… So I combed it all over again that night.

The next installment is an analysis of the self-actualization of promises that are common on the Internet,

In a word, seize the Promise idea, you can write a good Promise code.

Async and await will be explained in the next issue or the next issue. (I’m sorry that I want to finish it in one breath, but it’s too much. I also need to sort it out slowly and try to give you a high-quality article.)

I am a fresh graduate, recently maintained a public account with friends, the content is that we are in the transition from fresh graduate to the development of this way stepped on the pit, has been our step by step learning records, if interested in friends can pay attention to it, together with fuel ~