/**
* 一.Promise诞生了
* promise是什么?
* 承若,许诺---用于异步计算,可以将异步操作队列化;按照预期的顺序执行,返回符合预期的结果;可以在对象之间传递和操作promise,帮助我们处理队列。
* 异步产生的原因?
* 1.JS里很多操作是异步的(异步和同步的区别),异步操作的常见语法(事件执行与监听addEventListener; 回调,例如ajax)
* 2.浏览器中的异步操作
* 3.Node.js的出现---无阻塞和高并发,异步操作是保证,大量操作依赖回掉函数
* 异步回调的问题
* 1.嵌套层次很深,难以维护; 2.无法正常使用return和throw; 3.无法正常检索堆栈信息; 4.多个回调之间难以建立联系
* 二.Promise入门
* 详解
* Promise是一个代理对象,它和原先要进行的操作并没有关系
* 它通过引入一个回调,避免更多的回调
* 当promise的状态发生改变,就会触发.then()里的响应函数处理后续步骤
* promise的状态一经改变是不会再改变的
* promise实例一经创建,执行器就会立即执行,每一个then都会返回一个新的promise实例
* promise的三个状态
* pending 等待,初始状态
* fulfilled 实现,操作成功
* rejected 被否决,操作失败
* 简单范例
* 两步执行的范例:分两次顺序执行
* 1.假如对一个Promise已经完成了,再.then()会怎样?
操作是一个队列的状态,可以在后面追叙任意多个then,不管其前面的promise的状态是否完成,队列都会按照固定的顺序去执行(如果没有完成,就按顺序执行;如果没有完成,then也会得到前面promise的值)
* 2.then里不返回Promise===》假如.then()函数里边不返回新的promise,会怎样?
* 如果你不返回promise实例,那么它默认会去执行下一个环节
* 3..then()
* .then()接收两个函数作为参数,分别代表fulfilled和rejected
* .then()可以返回一个新的Promise实例,所以可以链式调用
* 当前面的promise状态改变时,.then()根据其最终的状态,选择特定的状态进行响应函数执行
* 状态响应函数可以返回新的promise,或其他值
* 如果返回新的promise,那么下一级.then()会在新的promise状态改变之后执行
* 如果返回其他任何值,则会立刻执行下一级 .then()
* 4..then()的嵌套
* 因为.then()返回的是promise实例,外边的会等待里面的then()执行完再执行外边的then()
* 可以将嵌套的then变成链式的then,方便理解
* 5.错误处理
* promise会自动捕获内部异常,并交给rejected响应函数处理,不过,捕获的是异步完成回调之后的错误信息,没有办法确定到底是那一步出错
* 两种做法:
* reject('错误信息').then(null,message => {})
* throw new Error('错误信息').catch(maessage => {}) //可以捕获前面每一步的错误,推荐使用
* 6.错误和then连用
* .catch()也会返回一个promise实例,建议在所有队列的最后都加上.catch()以避免漏掉错误处理造成的问题
* 三.Promise进阶
* 1.常用函数
* promise.all([p1,p2,p3,...]) ---- 用于将多个promise实例包装成一个新的promise实例,返回的是一个新的普通的promise实例;接收一个数组作为参数,数组里可以是promise对象,也可以是其他的值,但只有promise对象会等待状态的改变;当所有的子promise都完成,该promise才完成,返回值是全部值的数组;如果子promise中有任一个失败,该promise就失败,返回值是第一个执行失败的子promise的结果(这个的例子待纠正)
* .map() ,和.all()组合使用
* 实现队列,使用 .forEach() ,问题:没有把.then()产生的新Promise实例赋值给promise,没有生成队列;使用.reduce() 从数组的一端开始直到另一端遍历 ,问题:Promise实例创建之后会立即运行执行器代码,所以这个也无法达成队列效果
* .resolve() 返回一个fulfilled 的promise实例,或原始的promise
* 参数为空,返回一个状态为fulfilled的Promise实例
* 参数是一个和Promise无关的值,同上,不过fulfilled响应函数会得到这个参数
* 参数是thenable,就立即执行它的.then()
* .reject() 返回一个状态为rejected的promise的实例,或原始promise实例
* 参数为空,返回一个状态为rejected的promise实例
* 参数是一个跟promise无关的值,同上,不过rejected响应函数会得到这个参数。
* 参数为promise实例,则返回该实例,不做任何修改
* 与promise.resolve相比,不认thenable
* .race() 类似于all(), 区别在于它有任意一个完成就算完成,常见用法:把异步操作和定时器放在一起;如果定时器先触发,就认为超时,告知用户(超时提醒)
* 2.把回调包装成promise(封装)
* 好处:可读性更好;返回的结果可以加入任何promise队列
*
* 3.把任何异步操作包装成promise
* 假设需求:用户点击按钮,弹出确认弹窗;用户确认和取消有不同的处理。(定制弹窗)
* 4.jQuery中的promise,见jqXHR
* $.ajax(url,{
* dataType:'json'
* }).then(json => {
* //do something
* });
* 如果需要在ie中使用promise,有两个选择:
* 1.只想实现异步队列:jQuery.defered
* 2.需要兼容所有的平台:Bluebird,Promise polyfill
* fetch api: 是XMLHttpRequest的现代化替代方案
* 更强大也更友好;直接返回一个promise实例
* fetch('some.json').then(response => {
* return response.json();
* }).then(json => {
* //do something with json
* }).catch(err => {
* console.log(err);
* });
* promise的支持情况
*
* 5.异步函数---async/await: 赋予JS以顺序手法编写异步脚本的能力; 即保留异步运算的无阻塞特性,还继续使用同步的写法;还能正常使用return/try/catch
那么,为什么还要学Promise呢?
* async是在promise上计算的,会等待返回一个promise对象;async声明一个异步函数,await等待一个promise对象返回,例如:
* async function f1(){
* var x = await resolveAfter2Seconds(10);
* console.log(x);
* }
* f1(); //f1()是一个异步函数,后面可以用then继续下面的操作
*
* */
学习与面试题总结分析: