Promise实践
一、概念
Promise是异步编程的解决方案之一,与事件驱动+回调函数并列。
Promise是专门为异步编程设计的封闭的一次性用品,封闭体现在只有异步操作的结果能改变其状态,其他任何操作都不能改变其状态。一次性体现在一旦新建就会运行而且一旦状态改变,就不会再改变。
注意1:调用resolve或reject并不会中止Promise内代码的执行,不管是同步还是异步代码,就算是ajax这种异步操作,将这些异步操作添加到事件循环的末尾的动作也是同步的。但是理论上来说,resolve和reject调用之后Promise的状态一定会改变,根据它一次性的特点,它已经没有意义了,后面不应该有代码,可以在resolve和reject前加上return,这样它们后面的代码就不会执行了。
注意2:Promise会吃掉错误,Promise内部发生的语法错误不影响外部代码的执行。这也体现出Promise是真的封闭
二、语法
const promise = new Promise(function(resolve,reject){
// asynchronous code
if(/*success*/){
resolve(value);
}else{
reject(error);
}
});
进阶用法1:resolve或reject的参数是一个promise,这个参数的promise将决定外部promise的状态
const p1 = new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('fail')), 3000) }) const p2 = new Promise(function (resolve, reject) { setTimeout(() => resolve(p1), 1000) }) p2 .then(result => console.log(result)) .catch(error => console.log(error)) //Error:fail
进阶用法2:then和catch可以链式调用,返回一个新的Promise实例,如果在then中不显式返回一个promise实例,then会将你return的data(字符串啊什么的)当做默认promise对象的resolve的参数,并执行resolve(data)
进阶用法3:catch(error)是then(null,function(error))的别名,除了处理rejected状态,还可以捕获Promise中抛出的错误。
经测试,then中的reject处理函数也能捕获promise中抛出的错误,可以说,reject函数的作用等同于抛出错误。
错误具有冒泡性质,总会被后面的catch捕获。推荐使用catch代替then的第二个参数。
三、实例:https://github.com/WHITE-ILMARE/Front-End-Learning-Demos/tree/master/ES6/promise
1.控制最基础的异步——setTimeout();
2.对单个Ajax请求的控制
3.Promise.all:各个子Promise的结果会存储在数组中作为外部Promise实例resolved的参数。
若子Promise有catch方法,就调用自己的catch,若没有,就调用外部Promise实例的catch方法。就语义上来说,这样做阻止了子Promise的一次reject导致多次catch,比较有意义。可以根据需要,决定统一处理rejected还是定制化处理rejected。
四、理解
写了几个Promise实例,Promise的优点在哪?
1.形式上,想一下jquery中的$.get(url,callback(data)),如果用promise,可以写成new Promise(function(...){$.get(url,resolve(data))}).then(data),就是把传统的回调函数掏出来写在外边了,听说这是同步的写法,我还不明白什么叫同步的写法,没有回调就是同步的写法??总而言之,就是形式上的简化。
2.理解方式上,我在读了ES6 JavaScript Promise的感性认知« 张鑫旭-鑫空间-鑫生活 - zhangxinxu这篇文章后想到,将回调函数的写法转换成promise.then().then()这种写法易于让人读懂代码,更容易理解代码。因为这种写法代表一种逻辑,应该就是上一条说的同步的逻辑,更符合现实世界人们的思维方式,所以便于理解,提高了代码可读性和结构。
浙公网安备 33010602011771号