异步回调函数缺点:
嵌套层次很深,难以维护
无法正常使用return 和 throw
无法正常检索堆栈信息
多个回调之间难以建立联系
Promise
Promise对象用于异步计算。
可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。
可以在对象之间传递和操作Promise,帮助我们处理队列。
Promise
Promise对象用于异步计算。
可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。
可以在对象之间传递和操作Promise,帮助我们处理队列。
四种情况对应的答案:
Promise 三种状态
Pending 待定-初始状态
Fulfilled 实现-操作成功
rejected 被否决-操作失败
.then里面嵌套.then 会先将里面的执行完,再执行最外面的。
promise有多个then方法的时候会按照顺序依次执行
1、promise 状态发生改变后 pending => fulfilled/rejucted 会立刻触发.then里面的响应函数。状态一经改变就不可再改变
在多个回调之间难以建立联系
嵌套层次很深
无法正常使用return和throw
无法正常检索堆栈信息
主要用于异步计算
可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
可以在对象之间传递Promise,帮助我们处理队列
promise execution flow
promise execution flow
promist.all()
new Promise( resolve => { setTimeout( ()=> { resolve(); },1000); }) .then( ()=>{ console.log('start'); throw new Error('test err'); //下一个catch捕获 }) .catch( err=> { console.log('I catch', err); //throw new Error('another err'); //catch返回promise对象 }) .then( ()=> { //catch不throw error,then继续执行 console.log('arrive here'); }) .catch( err=> { console.log('No, I catch:', err); });
let promise = new Promise( resolve => { setTimeout( ()=>{ console.log('the promise fulfilled'); resolve('hello world'); },1000); }); setTimeout(()=>{ promise.then( value=>{ //调用之前promise console.log(value); }); },3000);
new Promise( resolve => { setTimeout( ()=> { resolve('hello'); }, 2000); }).then( value => { console.log(value); //value值为'hello' return new Promise( resolve => { setTimeout( ()=> { resolve('world') }, 2000); }); }).then( value=> { //value值world console.log( value + ' world'); });
new Promise( //实例声明 //executor执行器 function (resolve,reject){ // 异步 resolve(); //数据处理完成 reject(); //数据处理出错 } ).then(function A(){ //成功 }, function B(){ //失败 });
new Promise(..).then(..);
promise
async/await
ES2017新增运算符,新的语言元素。
赋予JavaScript以顺序手法编写异步脚本的能力!
既保留异步运算的无阻塞特性,还继续使用同步写法。
还能正常使用return/try/catch
Fetch API 是XMLHttpRequest的现代化替代方案。
更强大,也更友好。
直接返回一个Promise实例。
在IE中使用
jQuery.defered 只想实现异步队列
需要兼容所有平台:Bulebird Promise polyfill
把回调包装成Promise最为常见,它有两个显而易见的好处:
可读性好
返回的结果可以加入任何Promise队列
Promise.race()常见用法:
把异步操作和定时器放在一起
如果定时器先触发,就认为超时,告知用户
Promise.race()类似Promise.all()区别在于它有任意一个完成就算完成。
Promise.resolve()
返回一个fulfilled的Promise实例,或原始Promise实例。
参数为空,返回一个状态为fulfilled的Promise实例
参数时一个跟Promise无关的值,同上,不过fulfuilled响应函数会得到这个参数
参数为Promise实例,则返回该实例,不做任何修改
参数为thenable,立刻执行它的.then()
实现队列
有时候我们不希望所有动作一起发生,而是按照一定顺序,逐个进行。
常见错误:1.没有把.then()产生的新Promise实例赋值给promise,没有生成队列。
2.Promise实例创建之后,会立刻运行执行器代码,所以这个也无法达成队列的效果。
Promise其他常用函数,Promise.all()
批量执行
Promise.all([p1,p2,p3,...])用于将多个Promise实例,包装成有一个新的Promise实例。
返回的实例就是普通的Promise
接受一个数组作为参数。
数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变。
当所有子Promise都完成,该Promise完成,返回值是全部值得数组。
有任何一个失败,该Promise失败,返回值是第一个失败的子Promise的结果。
catch 也会返回一个Promise实例, 如果没有抛出错误,返回的实例也是成功状态的,所以接下来的then都会被执行
注意: 强烈建议在所有队列最后都加上.catch(),以避免漏掉错误处理造成意向不到的问题。
错误处理的两种做法:
reject('错误信息').then(null,message=>{])
throw new Error('错误信息').catch(message=>{})
推荐使用第二种,更加清晰好读,并且可以捕获前面的错误。