Promise of JavaScript asynchronous operation

Ten years in the world 2021-01-21 16:44:54
promise javascript asynchronous operation


because JavaScript Code is usually executed by a single thread , So I'm writing JavaScript Asynchronous operation is often used to improve the performance of the program . In general, asynchronous execution occurs in JavaScript Use in Callback function In the form of . But in recent years, driven by the community ,Promise Has become a JavaScript A standard for asynchronous programming , Use Promise Programming asynchronously , The maintainability of the code will be greatly improved , Especially in use Promise Replace multilayer Callback function The problem of nesting .

Promise brief introduction

Here's how to construct the simplest Promise Code example :

// structure Promise
const promise = new Promise(function (resolve, reject) {
// Asynchronous operation code
if ( Asynchronous operation succeeded ) {
resolve(this.response);
} else {
reject(this.status);
}
});
// promise Callback when state changes
promise.then(function (res) {
console.log(res); // Execute successful callback
}, function (error) {
console.log(error); // Execute failed callback
})

Promise yes JavaScript An object provided , Can pass new Keyword constructs this object .Promise Constructor takes a function as an argument , This function takes two other functions as arguments , Namely resolvereject, These two functions are made up of JavaScript The engine itself provides , No need for us to create it manually .

Promise Objects have three states , Namely :pending( Have in hand )、fulfilled( Have succeeded )、rejected( Failed ). There are two state changes , One is from pending Turn into fulfilled, The other is from pending Turn into rejected, Once the status changes , The state will solidify , Cannot be changed again . and resolve The role of will be Promise Object state from pending Turn into fulfilled,reject The role of the Promise Object state from pending Turn into rejected.

Usually we're passing it on to Promise Write some asynchronous code at the top of the function of the constructor , For example, one AJAX request , And then when the asynchronous code executes successfully , call resolve,resolve It's a function , It can receive parameters , So when we call it, we can pass the execution result of asynchronous code to it , here resolve The function has two functions , One is change Promise The status of is fulfilled, Second, it can pass in parameters to promise Example of then Method in the first callback function , To be used in subsequent operation . Called when asynchronous code execution fails reject function , here reject Functions also have two functions , One is change Promise The status of is rejected, The second is to pass in the parameters to promise Example of then Method in the second callback function .

When Promise Once the status changes , We can go through Promise Instance of object (promise Variable ) Of then Method to get the result of the asynchronous operation .then Method takes two callback functions as parameters , The first callback function will be in Promise The status changes to fulfilled Automatically call , The second callback function will be in Promise The status changes to rejected Automatically call . Each of these callback functions receives a parameter , The first callback function receives res The parameter is actually what we're doing Promise When the internal asynchronous code is executed successfully, it is passed to resolve Parameters of , The second callback function receives error The parameter is Promise When internal asynchronous code execution fails, it is passed to reject Parameters of .

That's all Promise Object execution process , Let's use an example to show Promise How to use it in practical code writing .

Let's take a look at a passage Callback function It's written as AJAX Example of the requested code :

function handleResponse() {
if (this.readyState === 4) {
if (this.status === 200) {
console.log(this.response);
} else {
console.log(this.status);
}
}
}
const request = new XMLHttpRequest();
request.open('GET', 'http://httpbin.org/get');
request.onreadystatechange = handleResponse;
request.send();

Writing Javascript This kind of code is very common , So how to use Promise How to write the above code ? Please see the following example :

const promise = new Promise(function (resolve, reject) {
function handleResponse() {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.response); // Call... When the request succeeds
} else {
reject(this.status); // Call... When the request fails
}
}
}
const request = new XMLHttpRequest();
request.open('GET', 'http://httpbin.org/get');
request.onreadystatechange = handleResponse;
request.send();
})
promise.then(function (res) {
console.log(res); // Successful callback
}, function (error) {
console.log(error); // Failed callback
})

That's through Promise To deal with it AJAX Writing . At first glance , I don't think the code has changed much , It's even more troublesome ? in fact , That's true , If you just send a simple AJAX In terms of request code, we really don't need to use Promise Writing , This only makes the code look more complex .

Promise What problems can be solved

that Promise What is the applicable scenario of , What problems can be solved ?

  1. Promise Perfect for solving Back to hell problem .
  2. Promise Solve the callback function can not be used return The problem of .

Let's see Promise How to solve these two problems . Suppose we need to call an interface to get a list of blogs published by users , And this interface needs to be logged in to be able to call . That is to say, the order in which we call interfaces must be : First call the login authentication interface to login , Then call the interface to get the user's blog list .

If you use jQuery send out AJAX Requested Callback function How to write it , It's possible that we'll write code like this :

// Send the first AJAX Request to log in
$.ajax({
type: 'GET',
url: 'http://localhost:3000/login',
success: function (res) {
// Login success callback function internal , Send a second AJAX Request for data
$.ajax({
type: 'GET',
url: 'http://localhost:3000/blog/list',
success: function (res) {
console.log(res);
},
error: function (xhr) {
console.log(xhr.status);
}
});
},
error: function (xhr) {
console.log(xhr.status);
}
});

You can see , Use Callback function The code written in form is nested . in other words , Every additional request , We are going to success Write another layer of nesting inside the callback function . If there are too many nesting levels , Then there will be JavaScript A headache —— Back to hell . The more levels of nesting , The harder the code is to understand , If there is an anomaly , So debugging will be a very painful process .

We try to use Promise To solve the above problems :

const getResponse = function (url) {
const promise = new Promise(function (resolve, reject) {
$.ajax({
type: 'GET',
url: url,
success: function (res) {
resolve(res);
},
error: function (xhr) {
reject(xhr);
}
});
});
return promise;
}
getResponse('http://localhost:3000/login').then(function (res) {
getResponse('http://localhost:3000/blog/list').then(function (res) {
console.log(res);
}, function (xhr) {
console.log(xhr.status);
})
}, function (xhr) {
console.log(xhr.status);
});

The above is the use of Promise Refactoring code , But if you look closely, you'll see : The code above is still in use Callback I want to write Promise Code . On the first call getResponse Function request http://localhost:3000/login After success , Code execution then Method , stay then Inside the method , Again called getResponse function , This time the request http://localhost:3000/blog/list Address , After success, execute the next then Method , stay then Method can successfully get the interface return result of user blog list .

In fact, the above code also exists Back to hell The problem of , Because if there are too many requests , We also need to call it in a nested function getResponse. There is no doubt that we have not got rid of Back to hell .

Let's see how to use it properly Promise Object solution Back to hell An example of :

const getResponse = function (url) {
const promise = new Promise(function (resolve, reject) {
$.ajax({
type: 'GET',
url: url,
success: function (res) {
resolve(res);
},
error: function (xhr) {
reject(xhr.status);
}
});
});
return promise;
}
getResponse('http://localhost:3000/login').then(function (res) {
return getResponse('http://localhost:3000/blog/list');
}, function (xhr) {
console.log(xhr.status);
}).then(function (res) {
console.log(res);
}, function (xhr) {
console.log(xhr.status);
});

stay Promise Interface ,then Method will return a new Promise example , So we can use the chain call approach ,then Method followed by another then Method , In theory, it can go on indefinitely .

Pay attention to the first then Inside the method , Calling getResponse('http://localhost:3000/blog/list') In front of the return. It's this return The existence of , It makes it possible to write without layer by layer nesting , To flatten the code .Promise After the example then Methods will execute in turn , Last time then Method internal return result , Will be passed in as a parameter to the next then Method . If you use a callback function , Because there's no way inside return, So you can only add infinite nesting to solve the problem .

This code can reflect Promise The real power of objects , It can flatten out all layers of nested code . Every additional request , Just add another one at the back then Method call , The code written in this way is much more intuitive , You don't have to write code with multiple layers of nesting .

Promise Of then Methods and catch Method

We know from the introduction above that Promise Of then Method takes two callback functions as parameters . actually , Its second parameter is not required , If you don't care about anomalies , So you can just write the first callback function .

Promise It also provides catch Method is designed to receive exceptions , It is written as follows :

getResponse('http://localhost:3000/login').then(function (res) {
return getResponse('http://localhost:3000/blog/list');
}).catch(function (xhr) {
console.log(xhr.status);
});

It's more intuitive to handle exceptions in this way , It also looks clearer , No use then Method passes in a second callback function to handle the exception , But alone in catch Method internal processing . in fact .catch(callback) Method is equivalent to .then(undefined, callback).

Promise Of all Methods and race Method

Promise Of all Methods can be used to Promise example , Merge into one Promise example .

What's the point ? Suppose we need to wait for multiple asynchronous operations to complete before we can execute the next logic , This is the use of all The best time to do it . Use in this case Callback function It's not easy to solve , While using Promise It's very simple .

We asked three times http://httpbin.org/get To simulate three asynchronous operations that need to wait , The code is as follows :

const p1 = getResponse('http://httpbin.org/get');
const p2 = getResponse('http://httpbin.org/get');
const p3 = getResponse('http://httpbin.org/get');
const p = Promise.all([p1, p2, p3]);
p.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});

all Method takes an array as an argument , Every item in an array is a Promise object ,Promise example p It's the merged object ,p1p2p3 The state of p The final state of .

Only p1p2p3 At the same time, they all become fulfilled when ,p The state of fulfilled. as long as p1p2p3 One of the states of becomes rejected,p The state of will become rejected. When p The state of becomes fulfilled when ,p1p2p3 The returned results of the will form a list , Automatically deliver to p Of then Callback function for method . And the order of this list is passed in by all Method p1p2p3 The order of decision .

When p1p2p3 Any state becomes rejected when , Only it doesn't have its own catch Method is called when all After the method catch Method . Otherwise, it will only call its own catch Method .

as for race Method usage and all The method is exactly the same , The difference is : as long as p1p2p3 One of the states of becomes fulfilled when ,p The state of will become fulfilled. This is also race The meaning of this word competition , as long as p1p2p3 One of the objects first changed state , that p And the state of it changes and solidifies . The code inside the other two objects will still execute , But the results are no longer useful .

Due to the use race All you need to do is put Promise.all([p1, p2, p3]) Switch to Promise.race([p1, p2, p3]) that will do , So I won't give you a code example here .

That's about Promise How to use it , in fact Promise It doesn't just provide these interfaces , But other interfaces are rarely used , So I'm not going to talk too much about it , When you are familiar with its usage, you can learn it further .

The starting address : https://jianghushinian.cn/
版权声明
本文为[Ten years in the world]所创,转载请带上原文链接,感谢
https://javamana.com/2021/01/20210121163744557W.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云