1.Promise是什么?
主要用于异步计算,可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。
可以在对象之间传递和操作Promise,帮助我们处理队列。
2.异步产生的原因
JavaScript为检查表单而生,创造它的首要目标是操作DOM,所以JavaScript的操作大多是异步的。
异步,A和B任务的交付顺序和安排顺序无关。
3.Promise详解
Promise是一个代理对象,它和原先要进行的操作并无关系。
它通过引入一个回调,避免更多的回调。
Promise 有3个状态:
pending【待定】初始状态
fulfilled【实现】操作成功
rejected【被否决】操作失败
当Promise状态发生改变,就会触发.then()里的响应函数处理后续步骤。
Promise状态如果已经改变,不会再变。
4. .then()
.then()接受两个函数作为参数,分别代表fulfilled和rejected
.then()返回一个新的Promise实例,所以它可以链式调用
当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行。
状态响应函数可以返回新的Promise,或其它值(不返回也可以,我们默认返回一个空)
如果返回新的Promise,那么下一级.then()会在新的Promise状态改变之后执行。
如果返回其它任何值,则会立刻执行下一级.then()
5. .then()里有.then()的情况
因为.then()返回的还是Promise实例
6.错误处理
Promise会自动捕获内部异常,并交给rejected响应函数处理
错误处理的两种做法:
1.reject(‘错误信息’).then(null.message = > {})
2.throw new Error('错误信息').catch(message = > {})
3.推荐使用第二种,更加清晰好读,并且可以捕获前面的错误。
7.catch() + .then()
强烈建议在所有队列最后都加上。catch(),以避免漏掉错误处理造成意想不到的问题。
8.Promise常用的函数
1.Promise.all()
Promise.all([p1,p2,p3,....])用于将多个Promise实例,包装成一个新的Promise实例。返回的实例就是普通Promise
它接受一个数组作为参数,数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变。
当所有子Promise都完成,该Promise完成,返回值是全部值的数组
有任何一个失败,该Promise失败,返回值是第一个失败的子Promise的结果
Promise.all()最常见就是和.map()连用。
实现队列
使用.forEach()
常见错误:没有爸.then()产生的新Promise实例赋给promise,没有生成队列。
使用.reduce()
常见错误:Promise实例创建之后,会立刻运行执行代码,所以这个也无法达成队列效果。
2.Promise.resolve()
返回一个fulfilled的Promise实例,或原始Promise实例。
参数为空,返回一个状态为fulfilled的Promise实例
参数是一个跟Promise无关的值,同上,不过fulfuilled响应函数会得到这个参数
参数为Promise实例,则返回该实例,不作任何修改。
参数为thenable,立刻执行它的.then()
3.Promise.reject()
返回一个rejected的Promise实例
Promise.reject()不认thenable
4.Promise.race()
类似Promise.all(),区别在于,它有任意一个完成,就算完成。
常见用法:
把异步操作和定时器放在一起,如果定时器按时触发,就认为超时,告知用户。
9.现实中的Promise
1.把回调包装成promise最为常见。它有两个显而易见的好处:
可读性更好
返回的结果可以加入任何Promise队列
2.把任何异步操作包装成Promise
假设需求:
用户点击按钮,弹出确认窗体
用户确认和取消有不同的处理
样式问题不能使用window.conform()
10.jQuery
jQuery已经实现了Promise。
11.兼容问题
如果需要在IE中使用Promise,有两个选择:
只想实现异步队列:jQuery.defered
需要兼容所有平台:Bluebird 或Promise polyfill
12.Fetch API
更强大,也更友好。
直接返回一个Promise实例。
13.async/await
ES2017新增运算符,新的语言元素。
赋予JavaScript以顺序首发便携异步脚本能力
既保留异步运算的无阻塞特性