Promise1

学习promise前先了解一个概念

1.1区别实列对象与函数的区别

<script>
 	//Funa这是一个普通的函数
	function Funa(){}    
	
	 //funb这是一个构造函数 是Funa的实例对象(简称对象,此时Funa已经是个韩函数对象)
	const funb = new Funa()   
	
	//这是时候发现Funa 的constructor属性中已经包含了包含了f funb()
	console.log(Funa.prototype) 

	console.log(Funa.bind({}))    //只有函数对象才有.bind(方法)
	
	Funa.call()   //Funa是函数对象
	
//比如果我们的jquery中的$符号就是一个函数对象
$("#dom")  //函数对象
$("#dom").get  //get就是函数对象的方法 
	
</script>

1.2二中类型的回调韩式

1.2.1同步回调

概念:立即执行、完全执行了才结束、不会放到回调队列中
列子:数组遍历的相关回调函数。promise的exctor函数

const array= [1,2,3,4,5,6,7,8,9] 
//这就是一个遍历的立即执行的回调函数
array.forEach(item=>{ //遍历回调,同步回调函数,不会放入队列、一上来就要执行完
	console.log("我是遍历的console>>>>>>>",item)
})
console.log("我是遍历之后的console")
//打印结果
//我是遍历的console>>>>>>> 1
//我是遍历的console>>>>>>> 2
//我是遍历的console>>>>>>> 3
//我是遍历的console>>>>>>> 4
//我是遍历的console>>>>>>> 5
//我是遍历的console>>>>>>> 6
//我是遍历的console>>>>>>> 7
//我是遍历的console>>>>>>> 8
//我是遍历的console>>>>>>> 9
//我是遍历之后的console

看的数来同步回调只有上面的forEach执行完了,才会执行下面的console

1.2.3异步回调

概念:不会立即回调、会放到回调队列中将来执行
例子:定时器回调/Ajax回调/promise成功失败的回调

setTimeout(()=>{ //异步回调函数,会放到队列中将来执行
    console.log("timeOut callBack")
},0)
console.log("setTimeout之后")

//打印结果
//setTimeout之后
//timeOut callBack

尽管setTimeout的时间为0,但还是执行后面的console

1.3 JS中error的处理

  1. 错误的处理
    Error:所有错误的父类型
    RegerenceError:应用类型的变量不存在
    TypeError:数据类型不争却的错误
    RangeErrror:数据值不再其允的范围内
    SyntaxError:语法错误

  2. 错误处理
    捕获错误:try … catch
    抛出错误:throw error

  3. 错误对象
    message属性:错误相关信息
    stack属性:韩式调用栈记录信息

常见的内置错误:
RegerenceError:应用类型的变量不存在

//打印一个不存在的变量
consoel.log(dfsadfdsafadsf)

在这里插入图片描述

TypeError:数据类型不正确的错误

//错误的使用
let b = null 
console,log(b.xxx)

在这里插入图片描述
RangeErrror:数据值不再其允的范围内
在这里插入图片描述

  function fn(){
	fn()
}
	fn()

SyntaxError:语法错误

 const a = " "" "	

1.3.1 try …catch

	try{
	let d 
	console.log(d.xxxx) 
	}catch(error){
		console.log(error)
	}

自定义抛出错误

function something (){
	if (Date.now()%2==1){
		console.log("当前时间为奇数,可以执行任务")
	}else{ //如果时间不是奇数,由调用者来处理
		throw new Error("我是跑出去的错误")
	}
}
//捕获处理异常

try {
	something()
}catch(error){
	alert(error.message)
}

在这里插入图片描述
龟龟 学废了嘛?

promise的理解和使用

2.1 promise是什么?

2.1.1 理解

  1. 抽象表达:promise是js中进行异步编程的新的解决方案,因为js是单线程的,但是在数据请求或者定时器的一些场景中,存在了异步,es6就出现了promise来解决异步。
  2. 具体表达:promise是一个构造函数、promise对象u哦你过来封装一个异步操作并可以获取其结果

2.1.2 promise 的状态改变

  1. pending 变为 resolved
  2. pending 变为 rejected
    说明:只有这两种,且一个promise对象只能改变一次,无论成功失败,都会由一个结果数据,success or error

2.1.3 promise 基本的基本流程

resloved
rejected
new Promise
执行异步操作
Promise对象
then回调onResloved
新的promise对象
Promise对象
catch回调onRejected

2.1.4 promise 的基本使用

		//1.创建一个新的Promise对象
		const promise = new Promise((resolve, reject) => { //执行器函数
			//2.执行异步操作任务
			setTimeout(() => {
			const time = Date.now() //如果当前时间是偶数就代表成功反之失败
			if (time % 2 == 0) {
			//3.1 如果成功了,调用resolve(value)
			resolve("现在是偶数,进入成功拉,现在的时间是"+time)
			} else {
			//3.2 如果失败了,调用reject(reson)
			reject("失败的数据,失败拉现在的时间是"+time)
				}
			}, 1000)
		})

		promise.then(
			(value) => { //接受得到成成功的value数据   onResolved
				console.log("成功的回调函数",value)
			},
			(reson) => {//接受得到失败的reason数据   onRejected
				console.log("失败的回调函数",reson)
			}
		)

2.2 为什么要用promise

2.2.1指定回调函数的方式更加灵活

  1. es6之前
    -es6之前是用纯回调函数解决异步,在写异步函数时指定成功和失败的回调,官方文档这样举例:
1.1使用纯回调函数//
createAudioFilrAsync(audioSetting,successCallbanc,failureCallback)

这种写发必须先指定回调函数,再开始异步。
2. 使用promise

1.2  使用promise //
 const promise = crrateAudioFlieAsync(audioSettings)//2
 setTimeout(()=>{
 	promise.then(successCallback.failureCallback)
 },3000)

promis的优势就是就promise执行完后,得到成功的数据后,再指定成功和失败的回调函数,(指定回调函数的方式更加灵活)

2.2.3支持链式调用,可以解决回调地狱

  1. 回调地狱
    回调地狱就是在多个函数嵌套,比如三个嵌套的函数,第二个函数是以第一个函数的结果为条件、第三个函数以第二个函数的结果为条件、他们是异步任务的话(比如请求数据),
   	//2.1回调地狱
   	doSomething(function(result){
   		doSomethingElse(result,function(newResult){
   			doThirdThing(newResult,function(finalResult){
   				console.log('最终结果'+finalResult)
   			},failureCallback)
   		},failureCallback)
   	},failureCallback)

这种纯回调代码难以阅读,处理问题难以维护
4. promise的写法

		// 2.2 使用promise的链式调用解决回调地狱的问题
		doSomething().then(function(result){
				return doSomethingElse(result)
		}).then(function(newResult){
			return doThirdThing(newResult)
		}).then(function(finalResult){
				console.log('得到最后的结果'+finalResult)
		}).catch(failureCallback)

这种编码方式就是链式调用,更清晰,异常处理更加方便、但是存在异常传透的问题,就是链式调用中任何一个promise出现异常的时候,都会走到catch这一步。
5. 终极解决方式 async/awit


   	// 2.3 async/await: 回调地狱的终极解决方案
   	async function requset (){
   		try{
   			const result = await doSomething()
   			const newResult = await doSomethingElse()
   			const finalResult = await doThirdThing()
   			console.log('得到最终结果'+finalResult)
   		}catch(error){
   			failureCallback(error)
   		}
   	}

asynv/await 取消了回调函数 最后会自己编译

2.3 如何使用promise(语法)

2.3.1API

  1. Promise构造函数:Promise(excutor){} //执行器
    excutor函数:同步执行(resolve,reject)=>{}
    resolve函数:内部定义成功时我们调用的函数 value=>{}
    reject函数:内部定义失败时我们调用的函数 reson=>{}
    说明:excutor会在Promise内部立即同步回调,异步才做在执行器中执行
  2. promise.prototype,then方法:(onResolved,onRejected)=>{}
    onResolved函数:成功的回调函数:value=>{}
    onReject函数:失败的回调函数:reson=>{}
    说明:指定用于得到成功value的成功回调和用于得到失败reson的失败回调,饭hi一个新的Promise对象
  3. Promise.prototype.catch方法:(onRejected)=>{}
    onRejected函数:失败的回调函数(reson)=>{}
    说明:then()的语法糖,相当于then(undefiend,inRejected)
  4. Promise.resolve方法:(value)=>{}
    value:成功的数据或promise对象
    说明:返回一个成功/失败的promise对象
  5. Promise.reject方法(reason)=>{}
    reson:失败的原因
    说明:返回一个失败的promise对象

举个栗子

		//产生一个成功值为1的promise对象
		const success1 = new Promise((resolve, reject) => {
			resolve(1)
		})
		//产生一个成功值为2的promise对象    语法糖
		const success2= Promise.resolve(2)
		const error3=Promise.reject(3)
		
		success1.then(value=>{
			console.log(value)    //打印结果为1 
		})
		success2.then(value=>{
			console.log(value)    //打印结果为2
		})
		error3.catch(reason=>{
			console.log(reason)  //打印结果为3
		})
		error3.then(null,reason =>{
			console.log(reason)  //打印结果为3
		})
  1. Promise.all()
const prALL= Promise.all([success1,success2,error3])
 	prALL.then(
 		value=>{
 			console.log("成功的值",value) //全部成功返回数组
 		},
 		reason=>{
 			console.log("失败的原因"+reason)  //一个失败全失败
 		},
 	)

  1. Promise.race()
  const pRace=	Promise.race([success1,success2,error3])
 	pRace.then(
 		value=>{
 			console.log("谁先完成",value)      //打印结果为1 
 		},
 		reason=>{
 			console.log("失败的原因"+reason)  //打印结果为3
 	})
 		},
 	)

2.3.2 Promise的几个关键问题

  1. 如何改变promise的状态?
    (1)resolve(value):如果当前是pending会变为resolved
    (2)reject(reson):当前如果是pedning就会变成rejectd
    (3)抛出异常:如果当前是pending就会变成rejected

  2. 一个promise指定多个成功失败回调函数,都会调用吗?
    当promise改变为对应状态时都会调用

 //出了resolve 和  reject 抛出之外    还可以通过js的throw 抛出
 let p =   new Promise(resolve,reject = >{
 	//resolve(1)
 	//reject(2)
 	thorw 3 
 })
 p.then(
 	value=>{}
 	reason=>{
 	console.log("reason",reason)    //打印结果为3
 }
)
  1. 改变promise状态指定回调函数谁先谁后?
    (1)都有可能,正常情况下是先指定回调再改变状态,但也见可以先改变状态再指定回调
    (2)如何先改变状态再指定回调?{(1.再执行器中直接调用resolve()/rejected()2.延迟更长时间再调用then())
    (3)什么时候才能得到数据?(1.如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据2.如果先改变状态,那当指定回调时,回调函数就会调用,得到数据)

  	//常规:先指定回调函数,后改变状态

new Promise((resolve,reject)=>{
  	setTimeout(()=>{ // 后改变状态(同时指定数据),异步执行回调函数
  		resolve(1)
  	},1000)
  }).then(
  	value=>{console.log(value)},
  	// reason=>{console.log(reason)}
  )

  //如果先改变状态,再指定回调函数  如何写呢?
   //1.最简单的就是去掉定时器  也就是去掉异步 
  new Promise((resolve,reject)=>{
  	resolve(1)     //先改变的状态(同时指定数据)
  }).then(  //后指定回调函数,异步执行回调函数
  	value=>{},
  	reason=>{},
  )

  //2. 设置一个比异步更长房时间的定时器?
  let p = new Promise((resolve,reject)=>{
  	setTimeout(()=>{ // 后改变状态(同时指定数据),异步执行回调函数
  		resolve(1)
  	},1000)
  })
//精妙?
  setTimeout(()=>{
  		p.then(
  			value=>{console.log("value",value)},
  			reason=>{console.log("reason",reason)}
  		)
  },1100)
  //小tips  如何分别一个函数是同步还是异步   ?  console  异步函数会在再队列里 先执行页面初始化代码函数  再执行异步队列里的函数

小例子
4. promise.then()返回的新的promise的结果由什么状态决定?
(1)简单表达:由then()指定的回调函数执行的结果决定
(1)详细表达:
a:如果抛出异常,新promise变为rejected。resaon为抛出的异常
b:如果返回的是非peomise的人一直,新promise变为resolved,value为返回值
c:如果返回的是另一个新的promise,此promise的结果就会变成新promise的结果

new Pormise((reslove,reject)=>{
	resolve(1)
}).then(
	value=>{ 
		console.log(value)   //打印结果为1
	}
).then(
	value=>{
		console.log(value)  //打印结果为undefined
	}
)

哇哦 amazing~
5. promise如何串联多个操作任务?
(1)promise的then返回一个新的promise,可以写的then()的链式调用
(2)通过then的链式调用串联多个同步/异步任务
.promise的中断

   //中断promise链
   在一个promise.then(
   return new  Promise(
   ()=>{}    //什么也不干
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值