【JavaScript-Promise】

JavaScript-Promise

拓展:箭头函数
1.去掉function 在()和()之间加=>
2.如果只有一个形参,可省略()
3.如果函数整体只有一句话,可省略{}
如果仅有一句话还是return必须省略return

  1. 什么是promise?
    专门保证多个异步任务必须顺序执行,且解决了回调低于问题的一项特殊技术
  2. 回调地域(callback hell)问题:
    a. 问题:如何让多个异步任务能顺序执行
    b. 错误:单纯按向后顺序调用三个异步函数,他们还是不会顺序执行!因为异步任务的特点就是,谁也不等谁!无法控制顺序!
    c. 正确:回调函数方式
    1. 第一个任务先把第二个任务装起来,但是暂不执行,第二个任务再把第三个任务装起来,也暂不执行
    2. 第一个任务最后一句话执行完毕之后,主动调用装有第二个任务的函数
    3. 第二个任务最后一句话执行完毕之后,主动调用装有第三个任务的函数
function liang(next){
	console.log(`liang开始`)
	setTimeout(function(){//setTimeout-定时器是异步:主程序不会等它执行完
		console.log(`liang到达终点!`)
	},6000)
	next()
}
function ran(next){
	console.log(`ran开始`)
	setTimeout(function(){//setTimeout-定时器是异步:主程序不会等它执行完
		console.log(`ran到达终点!`)
	},4000)
	next()
}
function dong(){
	console.log(`dong开始`)
	setTimeout(function(){//setTimeout-定时器是异步:主程序不会等它执行完
		console.log(`dong到达终点!`)
	},2000)
}
//错误
//liang()
//ran()
//dong()
//正确
liang(function(){ran(function(){dong()})})
  1. 何时使用promise:
    今后,只要多个异步函数必须顺序执行时,都用promise代替回调函数方式
  2. 如何:
    a. 所有异步函数不要加回调函数参数了!
    b. 用new Promise(function(door){ … })包裹住原来的异步函数代码。
    强调:原异步函数不需要做任何改变
    c. 在原异步函数最后执行的一句话之后,调用door开门!
    结果:自动执行.then()中串联的后续任务(下一个格子间,也可能是下一个函数)
    d. new Promise()是放在函数内创建的,所以,如果希望外部直到这里有一个格子间的对象可以串联,必须用return,必须用return new Promise()将其返回函数外部!
function 前一项异步函数{
	return new Promise(function(door){
		原异步函数内容
		异步函数最后一句话之后:door()
	})
})

e. 调用return new Promise()所在的异步任务函数,既可以执行异步函数的任务,又可以返回格子间,可用.then()与下一项任务串联
前一项任务().then(下一项任务)
下一项任务不要加(),因为不是立即执行
f. 多一个异步任务串联:任务1().then(任务2).then(任务3)

  1. 使用promise实现多个异步任务顺序执行
    在这里插入图片描述
function liang(){
	return new Promise(function(door){]
		console.log('liang开始')
		setTimeout(function(){
			console.log('liang结束')
			door()
		},6000)
	})
}
function ran(){
	return new Promise(function(door){]
		console.log('ran开始')
		setTimeout(function(){
			console.log('ran结束')
			door()
		},4000)
	})
}
function dong(){
	return new Promise(function(door){]
		console.log('dong开始')
		setTimeout(function(){
			console.log('dong结束')
			door()
		},2000)
	})
}
liang().then(ran).then(dong)//这里在then里执行的函数千万不要加(),----加()就代表立即执行
  1. 异步任务间传参:
    a. 其实door()开门时,是可以顺便传参的:door(实参值)
    b. 下一项任务,在自己的形参列表中定义形参变量接住上一个任务door()传过来的实参值
    在这里插入图片描述
function liang(){
	return new Promise(function(door){
		var bang='liang-接力棒'
		console.log('liang开始')
		setTimeout(function(){
			console.log('liang结束')
			door(bang)
		},6000)
	})
}
function ran(bang2){
	return new Promise(function(door){]
		console.log('ran开始')
		setTimeout(function(){
			console.log('ran结束')
			door(bang2)
		},4000)
	})
}
function dong(bang3){
	return new Promise(function(door){]
		console.log('dong开始')
		setTimeout(function(){
			console.log('dong结束')
			door(bang3)
		},2000)
	})
}
  1. 坑:door()中只能接收一个变量!
    a. 如果传多个变量,也只有第一个变量的值,可以传到下一个任务!
    b. 如果硬要穿多个值,可以放在数组或对象中传递:
    在这里插入图片描述
door({bang1,bang2})//对象简写:一个名字两用
  1. 错误处理:
    a.其实:new Promise赠送了两个门:

    1. door,通往正常路线下一个.then的门
    2. err,通过出错路线下一个.catch的门
    3. 所以:new Promise(function(door,err){ … })

    b.在异步任务中:

    1. 如果正常执行,开door(实参值),接下来走.then()
    2. 如果出错,开err(错误消息),接下来走最后一个.catch()

    c. 接住错误消息:
    .then(…).then(…).catch(function(errMsg{ … }))
    在这里插入图片描述

  2. Promise的三个状态(学名):***
    a. 三个状态 :pend(挂起/等待),fulfiled(成功),reject(失败)
    b. 其实new Promise真给我们的两个门也是有学名的,new Promise(function(resolve,reject){ … })
    c. 三个状态的切换:

    1. 执行new Promise()时,promise对象处于pending状态
    2. 当执行成功,我们调用resolve()开门时,整个promise对象就变成fulfilled状态,就自动调用.then()中的下一项任务
    3. 当执行过程中出错,我们调用reject()开门时,整个promise对象就变成rejected状态,就不在调用.then(),而是转向调用结尾的.catch()
  3. 多个异步任务同时执行,但是只有在最后一个任务执行完才做一件事情。
    a. 错误:顺序调用多个异步任务,在最后执行想要执行的代码
    b. 因为:主程序中的代码绝对不会等异步任务执行完才执行。一定是,多个异步任务刚开始执行时,主程序的代码就会立刻抢先执行!
    c. 正确:Promise.all([格子间1,格子间2,…]).then(最后一项任务)

Promise.all([liang(),ran(),dong()]).then(function(){})
//ES7 异步 函数自调
(
	asyn function(){
		await liang()
		await ran()
		await dong()
		console.log('比赛结束')
	}
)
//其实:asyn是整个串联的异步任务还是异步任务,不会变成同步的回主程序执行,所以必须写async
//await是让后续程序,必须等待单亲函数执行完,才能继续执行
//每个异步函数resolve(返回值),可用var 变量= 的方式接住
(
	asyn function(){
		try{
			var bang = await liang()
			bang = await ran(bang )
			bang = await dong(bang )
			console.log('比赛结束')
		}catch(e){
			......
		}
	}
)
//try{...}catch(e){}结构同样可以接住promise函数中reject抛出的错误

d. 原理:

  1. all后的数组中每个格子间的异步任务都是并发执行的!谁也不等谁!
  2. 但是,all后的.then()注定会等最慢的一个格子间执行完,才自动执行!

e.promise.all的返回值:

  1. 接:promise.all([…]).then(function(arr){…})
  2. arr中接到的返回值得顺序:和all中异步函数的顺序一致,与执行结束的先后顺序无关!

f.错误处理:
1. new Promise()其实增了两个门
new Promise(function(door,err){ … })
2. 异步任务内部:
i.如果执行成功,就调用door()走.then()
ii. 如果执行出错,就调用err(错误提示)走.catch()
3. 调用时,接住错误信息:
.then().then().catch(function(errMsg){ … })
//之前异步惹怒中err()中抛出什么实参值
//最后catch()中形参errMsg就接住什么实参值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值