A detailed introduction to Promises in JavaScript
1. Foreword
JavaScript is single-threaded and can only execute one task at a time. When a task takes a long time, subsequent tasks must wait. So, is there any way to solve this kind of problem? (Leave aside WebWorker), that is to let the code execute asynchronously. What does it mean? For example, when making an Ajax asynchronous request, the value of readyState is continuously monitored to determine the execution of the specified callback function.
There are usually three types of asynchronous execution, callback functions, event listening, and publish and subscribe. Event listening and publish and subscribe are actually similar, but the latter is more robust.
Such as callback function, callback function is the simplest programming idea applied in asynchronous execution. As follows:
function async(item,callback){ console.log(item); setTimeout(function(){ callback(item+1); },1000); }
In the above example, when the async function is executed, the printing operation is completed, and the callback function is executed after 1 second (but not necessarily 1 second, see "setTimeout things" for details).
The main purpose of asynchronous is to handle non-blocking and improve performance. Imagine if an operation requires multiple async function operations, as follows:
async(1, function(item){ async(item, function(item){ async(item, function(item){ console.log('To be continued..'); }); }); });
Isn’t it a bit difficult to read?
For another example, in order to make the above code more robust, we can add exception capture. In asynchronous mode, exception handling is distributed in different callback functions. We cannot handle exceptions through try...catch when calling, so it is difficult to do it effectively and clearly.
Ouch, what should I do?
唔唔唔唔, 唔唔唔唔—Promise makes its debut.
If you use ES6 Promise to optimize the above code, you can get:
function opration(item){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ resolve(item+1); },1000); }); console.log(item); return p; } function failed(e){ console.log(e); } Promise.resolve(1).then(opration).then(opration).then(opration).catch(failed);
Using Promise The optimized code has obvious advantages, turning the callback function into a chain call , avoids layers of nesting, makes the program flow clear, and handles errors thrown by one or more callback functions uniformly through the catch method.
Oh, that’s good. So who is this Promise in ES6? What are the specific usage rules? Let's explore it together.
2. Overview of Promise
Promise is a solution for asynchronous programming, which is more reasonable than traditional solutions (callbacks and events) and more powerful. It was first proposed and implemented by the community. ES6 wrote it into the language standard, unified its usage, and provided Promise objects natively.
Promise The object has and only three states:
1, pending: the asynchronous operation is not completed.
2, resolved: The asynchronous operation has been completed.
3, rejected: The asynchronous operation failed.
Also, there are only two modes of change in these three states, and once the state changes, it will not change again:
1, Asynchronous operation from pending to resolved ;
2, Asynchronous operation from pending to rejected;
Okay, since it belongs to the ES6 specification, we can directly print out the Promise through chrome and take a look This thing:
Well, It is clear at a glance that Promise is a constructor, Ook, so through it, we can instantiate our own Promise object , and make use of it.
3. Promise Getting Started Guide
Since Promise is a constructor, let’s take a look at the new one first. As follows:
var p = new Promise();
and execute the above code, the chrome screenshot is as follows:
Why is the error reported?
Oh, by the way, the Promise constructor requires a function as its parameter, and the function as a parameter has two parameters. The function of the first parameter is when the asynchronous operation changes from pending to resolved. for it to be called when; the second parameter is used for it to be called when the asynchronous operation changes from pending to rejected.
For example, I named the first parameter of the anonymous function resolve; the second parameter was named reject. The Demo is as follows:
var p = new Promise(function(resolve, reject){ console.log('new一个Promise对象'); setTimeout(function(){ resolve('Monkey'); },1000); });
and execute the above code. The chrome screenshot is as follows:
##Special reminder: When passing in an anonymous function as a constructor When we use new as the parameter of function Promise, the anonymous function has already been executed, as shown in the figure above.
Hey, in the above code, we use the setTimeout timer in the anonymous function and call resolve after 1 second. Why is there no undefined or error reported? ! This is the power of Promise. Because of this, we can rewrite asynchronous operations into elegant chain calls. How to call it? Remember, in the "Promise Overview" section, we printed Promise through chrome and used the area in the red line box? Among them, there is a then method (Promise.prototype.then) in the Promise prototype. Through this then method, it is enough. As follows:p.then(function(value){ console.log(value); });
好了,当then执行完后,如果我们想继续在其之后看,使用then方法链式调用,有两种情况,一种是直接返回非Promise对象的结果;另一种是返回Promise对象的结果。
1、返回非Promise对象的结果:紧跟着的then方法,resolve立刻执行。并可使用前一个then方法返回的结果。如下:
p.then(function(value){ console.log(value); //返回非Promise对象,如我的对象 return { name: 'Dorie', age: 18 }; }).then(function(obj){ console.log(obj.name); });
执行上述完整代码,chrome截图如下:
2、返回Promise对象的结果:紧跟着的then方法,与new Promise后的then方法一样,需等待前面的异步执行完后,resolve方可被执行。如下:
p.then(function(value){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ var message = value + ' V Dorie' resolve(message); },1000); }); console.log(value); //返回一个Promise对象 return p; }).then(function(value){ console.log(value); });
执行上述完整代码,chrome截图如下:
那么,当创建、执行Promise方法中有异常报错,如何捕获呢?
Promise.prototype.catch原型方法,就是为其而设定的。它具有冒泡的特性,比如当创建Promise实例时,就出错了,错误消息就会通过链式调用的这条链,一直追溯到catch方法,如果找到尽头都没有,就报错,并且再找到catch之前的所有then方法都不能执行了。Demo如下(代码太长,请自行展开):
<!DOCTYPE html> <head> <title>test</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head> <body> <script> var p = new Promise(function(resolve, reject){ //M未定义 console.log(M); setTimeout(function(){ resolve('Monkey'); },1000); }); p.then(function(value){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ var message = value + ' V Dorie' resolve(message); },1000); }); console.log(value); //返回一个Promise对象 return p; }).then(function(value){ console.log(value); return 'next is catch'; }).catch(function(e){ console.log(e); }).then(function(value){ console.log('execute,but value is ' + value); }); </script> </body> </html>
执行上述代码,chrome截图如下:
好了,到这里,我们已经了解了最常用的Promise.prototype.then和Promise.prototype.catch这两个原型方法。另外,像Promise构造函数还有属于自身的方法,如all、rece、resolve、reject等,详情请点击这里(here)。
通过一路上对Promise的讲述,我们也有了一定的认识,其实Promise并没有想象中的那么难以理解嘛。懂得Promise概念后,其实我们自己也可以实现一个简易版的Promise。下面就一同尝试实现一个呗。
四、模拟Promise
假设:有三个异步操作方法f1,f2,f3,且f2依赖于f1,f3依赖于f2。如果,我们采用ES6中Promise链式调用的思想,我们可以将程序编写成这样:
f1().then(f2).then(f3);
那么,通过上面这一系列链式调用,怎样才能达到与ES6中Promise相似的功能呢?
初步想法:首先将上述链式调用的f2、f3保存到f1中,当f1中的异步执行完后,再调用执行f2,并将f1中的f3保存到f2中,最后,等f2中的异步执行完毕后,调用执行f3。详细构思图,如下:
从上图可知,由于f1、f2 、f3是可变得,所以存储数组队列thens,可放入,我们即将创建的模拟Promise构造函数中。具体实现代码如下:
//模拟Promise function Promise(){ this.thens = []; }; Promise.prototype = { constructor: Promise, then: function(callback){ this.thens.push(callback); return this; } };
并且,需要一个Promise.prototype.resolve原型方法,来实现:当f1异步执行完后,执行紧接着f1后then中的f2方法,并将后续then中方法,嫁接到f2中,如f3。具体实现代码如下:
//模拟Promise,增加resolve原型方法 function Promise(){ this.thens = []; }; Promise.prototype = { constructor: Promise, then: function(callback){ this.thens.push(callback); return this; }, resolve: function(){ var t = this.thens.shift(), p; if(t){ p = t.apply(null,arguments); if(p instanceof Promise){ p.thens = this.thens; } } } };
测试代码(代码太长,自行打开并运行)。
function f1() { var promise = new Promise(); setTimeout(function () { console.log(1); promise.resolve(); }, 1500) return promise; } function f2() { var promise = new Promise(); setTimeout(function () { console.log(2); promise.resolve(); }, 1500); return promise; } function f3() { var promise = new Promise(); setTimeout(function () { console.log(3); promise.resolve(); }, 1500) return promise; } f1().then(f2).then(f3);
仔细品味,上述实现的Promise.prototype.resolve方法还不够完美,因为它只能够满足于f1、f2、f3等方法都是使用模拟的Promise异步执行的情况。而,当其中有不是返回的Promise对象的呢,而是返回一个数字,亦或是什么也不返回,该怎么办?所以,针对以上提出的种种可能,再次改进resolve。改善代码如下:
//模拟Promise,改善resolve原型方法 var Promise = function () { this.thens = []; }; Promise.prototype = { constructor: Promise, then: function(callback){ this.thens.push(callback); return this; }, resolve: function () { var t,p; t = this.thens.shift(); t && (p = t.apply(null, arguments)); while(t && !(p instanceof Promise)){ t = this.thens.shift(); t && (p = t.call(null, p)); } if(this.thens.length){ p.thens = this.thens; }; } }
测试代码(代码太长,自行打开并运行)。
function f1() { var promise = new Promise(); setTimeout(function () { console.log(1); promise.resolve(); }, 1500) return promise; } function f2() { var promise = new Promise(); setTimeout(function () { console.log(2); promise.resolve(); }, 1500); return promise; } function f3() { var promise = new Promise(); setTimeout(function () { console.log(3); promise.resolve(); }, 1500) return promise; } function f4() { console.log(4); return 11; } function f5(x) { console.log(x+1); } function f6() { var promise = new Promise(); setTimeout(function () { console.log(6); promise.resolve(); }, 1500) return promise; } function f7() { console.log(7); } var that = f1().then(f2).then(f3).then(f4).then(f5).then(f6).then(f7);
好了,初步模拟的Promise就OK啦。
吼吼,对于Promise,我们这一路走来,发现原来也不过如此呢。
以上就是详细介绍JavaScript 中的 Promise的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data
