知识点1:rosolve是执行下一步then()
// Promise { let ajax=function(){ console.log('执行2'); return new Promise(function(resolve,reject){ setTimeout(function(){ resolve() },1000); }) } ajax().then(function(){ console.log('promise','timeout2'); }) }
知识点2:允许多个下一步(then()里面再嵌Promise实例)
{ // 允许多个下一步 let ajax=function(){ console.log('执行3'); return new Promise(function(resolve,reject){ setTimeout(function(){ resolve() //允许下一步then },1000); }) } ajax() .then(function(){ return new Promise(function(resolve,reject){ setTimeout(function(){ resolve(); },2000); }); }) .then(function(){ console.log('timeout3'); }) }
知识点3:抛错时处理
{ // 抛错时处理 let ajax=function(num){ console.log('执行4'); return new Promise(function(resolve,reject){ if(num>5){ resolve() }else { throw new Error('出错了') } }) } ajax(6).then(function(){ console.log('log',6); }).catch(function(err){ console.log('catch',err); }); ajax(3).then(function(){ console.log('log',3); }).catch(function(err){ console.log('catch',err); }); }
应用场景:图片加载( Promise.all([]).then() 和 Promise.race([]).then() )
场景1:多张图片加载,实现所有图片加载完,再一起出现在页面上,提高用户体验
{ // 所有图片加载完再添加到页面 function loadImg(src){ return new Promise((resolve,reject)=>{ let img=document.createElement('img'); img.src=src; img.onload=function(){ resolve(img); } img.onerror=function(err){ reject(err); } }) } function showImgs(imgs){ imgs.forEach(function(img){ document.body.appendChild(img); }) } Promise.all([ //all是把多个Promise实例,只有所有合成一个Promise实例,只有所有Promise实例状态都发生变化时,才会生成新的Promise实例 loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png'), loadImg('https://cdn.baigebao.com/upload/pc/20181008/5bbad45787a22.png'), loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png') ]).then(showImgs); }
场景2:有一个图片加载完成就添加到桌面
{ // 有一个图片加载完成就添加到桌面 function loadImg(src){ return new Promise((resolve,reject)=>{ let img=document.createElement('img'); img.src=src; img.onload=function(){ resolve(img); } img.onerror=function(err){ reject(err); } }) } function showImgs(img){ let p=document.createElement('p'); p.appendChild(img); document.body.appendChild(p); } Promise.race([ //只要有一个状态改变就先显示,只显示一张 loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png'), loadImg('https://cdn.baigebao.com/upload/pc/20181008/5bbad45787a22.png'), loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png') ]).then(showImgs); }
注意:
promise中的resolved 总是晚于本轮循环中的同步任务
例子:
new Promise((resolve, reject) => { resolve(1); console.log(2); }).then(r => { console.log(r); }); // 2 // 1
调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。这是因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
一般来说,调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。
new Promise((resolve, reject) => { return resolve(1); // 后面的语句不会执行 console.log(2); })