1.Promise

promise 是ES6新增异步解决方案

    Promise  generator   ===> ES7 async/await

    Promise(承诺) 表示未来的某个时间一定会返回一个承诺的结果给你

    Promise 是一个容器,里面包裹了一些异步操作,它表示一个预计会在未来完成的异步操作

    Promise有三种状态: pending(进行中) fulfilled(已成功) rejected(已失败)

    Promise接受一个函数做为参数,这个回调函数有两个参数:这两个回调函数只要没有调用就一直是pendding的状态(这两个回调函数一个是  resolve成功后的回调函数 一个是 reject失败后的回调函数)
       Promise状态变化pending =>fulfilled 或者 pending=>rejected 且不可逆的,而且一旦执行成功状态就会凝固,会一直保持这个状态,不会在发生其他变化了

        Promise状态一旦发生改变就会触发promise的then方法,then方法中有两个默认回调函数,一个是成功后的回调resolve,一个是失败后的回调reject

    Promise实例上 有三个api

    then(resolve=>{},reject=>{}) 方法中有两个回调函数 分别表示成功后的回调 和失败后的回调

    catch(err=>{}) 在创建或者使用promise的时候,如果代码报错那么会自动的走then.reject 如果在then中没有reject回调,会在catch中进行错误捕获, catch方法也会捕获在then方法中发生任何错误

    finally(()=>{})  无论promise执行成功或者失败,也无论catch方法是否执行, 最终finally都会执行

1.一旦promise创建成功就会立即执行(new Promise())


		console.log(1);
		let p1=new Promise((resolve,reject)=>{
			resolve('1') //成功后的回调
			reject('2')//失败后的回调
			console.log(2);
		})	
		console.log(p1); //Promise
		p1.then((resolve)=>{//异步操作
			// resolve 成功后的结果
			console.log(3);
			console.log("resolve 成功后的结果",resolve);//1
			//如果成功则不会走reject
		},(reject)=>{
			// reject失败后的结果
			console.log("reject 失败后的结果",reject);//2
		})
		console.log(4);

上述代码中他们的打印数字顺序是1243,代码从上往下执行,promise里面是同步的,它的then方法是异步的所以放在了最后。

promise的手动报错的方法: throw new Error("手动报错"),打上这个代码手动报错后就会走reject或者catch方法

2.promise错误捕获 catch

        在创建或者使用promise的时候,如果代码报错那么会自动的走then.reject 如果在then中没有reject回调,会在catch中进行错误捕获, catch方法也会捕获在then方法中发生任何错误

		let p1=new Promise((resolve,reject)=>{
			if(1<0){
				resolve(1)
			}else{
				reject(2)
			}
		})
		p1.then((resolve)=>{
			throw new Error('手动报错')
			console.log('resolve 成功后的结果', resolve);
		}).catch((err)=>{
			console.log("catch err==>",err);
		})
		//返回结果是:catch err==> 2

3.promise.finally方法

无论promise执行成功或者失败,也无论catch方法是否执行, 最终finally都会执行

		let p1=new Promise((resolve,reject)=>{
			if(1>0){
				throw new Error('手动报错')
				resolve(1)
			}else{
				reject(2)
			}
		})
		p1.then((resolve)=>{
			console.log('resolve 成功后的结果',resolve);
		},(reject)=>{
			console.log("reject 失败后的结果",reject);
		}).catch(err=>{
			console.log("catch err==>",err);
		}).finally(()=>{
			console.log("finally fin===>");
		})
		//此时会走reject打印:'reject 失败后的结果 Error: 手动报错'
		//同时会走finally打印: finally fin===>

2.Promise的API:应用程序接口

 1.Promise.resolve

 2.Promise.reject

 3.Promise.all(): 如果都成功就正常返回,如果有一个失败,那么都会认为是失败的 

     Promise.all方法 参数是多个promise对象组成的数组, 返回值是一个新的promise对象

     如果参数中的promise对象都成功就正常返回,并且promiseAll方法中的每一个promise都是并行状态,当全部完成之后就会自动的调用promise.all().then()方法.

   如果参数中的promise对象有任意一个没有正常返回,那么整个pAll都会认为是失败的,并且把失败的这个promise对象的返回值直接输出 其他的就不会在继续执行了

		let p1 = new Promise((resolve, reject) => {
            setTimeout(() => {//模拟异步
                resolve("p1")
            }, 1000)
        });
		let p2 = new Promise((resolve, reject) => {
            setTimeout(() => {//模拟异步
                resolve("p2")
            }, 5000)
        });
        let p3 = new Promise((resolve, reject) => {
            setTimeout(() => {//模拟异步
                reject("p3")
            }, 2000)
        });
        let pAll = Promise.all([p1, p2, p3]);
		pAll.then( resolve => {
                console.log("成功后的回调",resolve);
                //"成功后的回调",["p1", "p2", "p3"]
            },
            reject => {
                console.log("失败后的回调",reject);
            })
	//由于p3里面返回的是失败的,all方法就会走reject打印:失败后的回调 p3
    //如果都是成功则all方法会走resolve打印:成功后的回调 (3) ["p1", "p2", "p3"]

4.Promise.race()

Promise.race方法返回的也是一个promise对象, race方法谁先有结果就返回谁,无论成功还是失败(成功的就走resolve,失败就会在reject中返回)

		let p1 = new Promise((resolve, reject) => {
            setTimeout(() => {//模拟异步
                reject("p1")
            }, 1000)
        });
        let p2 = new Promise((resolve, reject) => {
            setTimeout(() => {//模拟异步
                resolve("p2")
            }, 5000)
        });
        let p3 = new Promise((resolve, reject) => {
            setTimeout(() => {//模拟异步
                resolve("p3")
            }, 2000)
        });
        let pRace = Promise.race([p1, p2, p3]);
        pRace.then(
            resolve => {
                console.log("成功后的回调",resolve);//成功后的回调 p1
            },
            reject => {
                console.log("失败后的回调",reject);//失败后的回调 p1
            })
	 //rece方法是谁先有结果先返回谁,由于p1时间最短所以会走reject打印:失败后的回调 p1

3.PromiseAPI和应用

1.promise.all方法

需求:有三张图片 ,如果这三张图片都加载完成 那么就直接显示到页面中 否则就不展示

  var imgSrc1 = 'https://desk-fd.zol-img.com.cn/t_s1920x1200c5/g5/M00/0B/0D/ChMkJlvfvrWIcWxTAAVwJpEWx6kAAs9wwEITscABXA-520.jpg'
  var imgSrc2 = 'https://desk-fd.zol-img.com.cn/t_s1920x1080c5/g5/M00/0B/0D/ChMkJlvfwAeIRMZcAAVF6izrBzIAAs9xAMyo3YABUYC824.jpg'
  var imgSrc3 = 'https://desk-fd.zol-img.com.cn/t_s1920x1080c5/g5/M00/05/06/ChMkJ1xJk6mIBBi-AAX3ilTYbAcAAujyAEja8wABfei891.jpg'
		var imgBox = document.getElementById('imgBox')
		var loadImg = (arg) => {
			return new Promise((resolve,reject)=>{
			//    配置定时器,用来看管是否在一定时间内完成,如果没有就报超时
				setTimeout(() => {
					reject('超時')
				}, 5000);
				// 如果一定时间内完成会走以下代码:
				// 创建一个img标签
				var img = document.createElement('img')
				// /当图片标签获得scr属性的时候,图片就开始被加载
				img.setAttribute('src',arg)
				// 当图片加载完成会触发这个onload回调函数
				img.onload = () => {
					resolve(img)
				}
			})
		}
   // 使用promise的api:all方法,调用三次加载图片函数
   //如果都成功了,那么会返回成功后promise的resolve方法,如果有一个失败就会返回失败
   Promise.all([loadImg(imgSrc1),loadImg(imgSrc2),loadImg(imgSrc3)]).then(resolve=>{
		// resolve==> [图片1,图片2,图片3]
		for(var i = 0 ; i < resolve.length ; i++ ){
		// 将返回的img标签追加到元素中
			imgBox.appendChild(resolve[i])
		}
	    }).catch(err=>{
			alert(err)
		})

2.promise.race方法

需求:有一张图片 ,当这张图片的加载时间超过1s的时候,就不去加载了,并且在页面中显示加载超时,如果1s内完成了加载,那么就在页面中进行展示

		var loadingImg = (arg) => {
			var src = arg || 'https://desk-fd.zol-img.com.cn/t_s1920x1080c5/g5/M00/05/06/ChMkJ1xJk6mIBBi-AAX3ilTYbAcAAujyAEja8wABfei891.jpg'
			return new Promise((reslove,reject)=>{
				var img = document.createElement('img')//创建标签
				img.setAttribute('src',src)//给img标签添加src属性
				img.onload = () => {//图片加载完成会触发这个onload回调函数
					reslove(img)
				}
			})
		}
		//设置timeOut函数方法
		var timeOut = () => {
			//设置一个定时器
			return new Promise((reslove,reject)=>{
				setTimeout(()=>{
					reject('图片加载超时')
				},2000)
			})
		}
   //使用promise.race方法来判断成功与否,如果2秒内成功就显示照片,否则显示图片超时
		Promise.race([loadingImg(),timeOut()]).then(res=>{
			document.body.appendChild(res)
		}).catch(err=>{
			alert(err)
		})

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐