如何理解promise 续一
某些关于promise的问题
能否执行多个回调?
当promise改变为对应状态时都会调用
let p = new Promise((resolve , reject) =>{resolve('success')})p.then(v=>{console.log(v)})p.then(v=>{alert(v)})
promise.then()返回的新promise的结果状态由什么决定
由then()指定的回调函数执行的结果决定
- 如果抛出异常,新promise变为rejected,reason为抛出的异常
let p = new Promise((resolve, reject) => {resolve('success')})let result = p.then(v => {throw '错误'}, err => {console.log(err)})console.log(result)
- 如果返回的是非promise的任意值,新promise变为resolved,value为返回的值
let p = new Promise((resolve, reject) => {resolve('success')})let result = p.then(v => {return 123}, err => {console.log(err)})console.log(result)
- 如果返回的是另一个新promise,此promise的结果就会成为新promise的结果
let p = new Promise((resolve, reject) => {resolve('success')})let result = p.then(v => {return new Promise((resolve, reject)=>{resolve('ok')})}, err => {console.log(err)})console.log(result)
promise如何串连多个操作任务
- promise的then()返回一个新的promise,可以写成then()的链式调用
- 通过then的链式调用串连多个同步/异步任务
let p = new Promise((resolve, reject) => {resolve('success')})let result = p.then(v => {return new Promise((resolve, reject)=>{resolve('ok')})}).then(value=>{console.log(value)})
let p = new Promise((resolve, reject) => {resolve('success')})let result = p.then(v => {return new Promise((resolve, reject)=>{resolve('ok')})}).then(value=>{console.log(value)}).then(value=>{console.log(value)})
第二个undefined 产生的原因:
是因为then的返回结果是promise ,promise的返回状态由这个promise的返回值决定的;但是代码中的第一个then的返回值没有写,则第二个的结果就是undefined
promise 异常传透
- 当使用promise的then链式调用时,可以在最后指定失败的回调
- 前面任何操作出了异常,都会传到最后失败的回调中处理
let p = new Promise((resolve, reject) => {reject('fail')})let result = p.then(v => {return new Promise((resolve, reject)=>{resolve('ok')})}).then(value=>{console.log(value)}).then(value=>{console.log(value)}).catch(err=>{console.log(err)})
let p = new Promise((resolve, reject) => {resolve('success')})let result = p.then(v => {return new Promise((resolve, reject)=>{resolve('ok')})}).then(value=>{throw 'fail1'}).then(value=>{console.log(value)}).catch(err=>{console.log(err)})
中断promise 链
let p = new Promise((resolve, reject) => {resolve('success')})let result = p.then(v => {console.log(11)return new Promise(()=>{})}).then(value=>{throw 'fail1'}).then(value=>{console.log(value)}).catch(err=>{console.log(err)})
改编promise状态的方式
- 调用resolve()
- 调用rejecte()
- 抛出异常【throw】
尝试自定义promise搭建
在html 页面中,先将promise的使用结构搭建出来
<script type="text/javascript">let p =new Promise((resolve,reject)=>{resolve('success')})p.then(data=>{console.log(data)},err=>{console.warn(err)})</script>
新建一个promise.js文件,在html中引入这个promise
<script src="../js/promise.js" type="text/javascript" charset="utf-8"></script>
//覆盖Promise
function Promise(exectuor){/*保存是实例对象的this;避免在赋值时,this指向的时window比如:在resolve 中,如果像下面赋值,是无法得到对应的赋值结果的this.PromiseState="resolved"this.PromiseResult=data*/const self =this;//添加属性this.PromiseState ="pending"this.PromiseResult = null;// resolve 函数——表示成功执行的函数function resolve(data){self.PromiseState="resolved"self.PromiseResult=data// 修改对象状态 promiseState// 修改对象结果值 promiseResult}//reject 函数——表示失败执行的函数function reject(data){// 修改对象状态 promiseState// 修改对象结果值 promiseResultself.PromiseState="rejected"self.PromiseResult=data}//同步调用exectuorexectuor(resolve,reject);
}
//添加then 方法
Promise.prototype.then= function(onResolved,onRejected){
}
处理promise中 状态只能修改一次
function resolve(data){if(self.PromiseState !== 'pending') returnself.PromiseState="resolved"self.PromiseResult=data
}
处理异常请求
//使用try---catch 来处理 抛出异常改变 对象状态和 对象结果值try{//同步调用exectuorexectuor(resolve,reject);}catch (e){reject(e)}
完成then 方法
在promise.js 中then 方法中添加
//调用回调函数 if(this.PromiseState === 'resolved'){onResolved(this.PromiseResult);}if(this.PromiseState === 'rejected'){onRejected(this.PromiseResult);}
处理异常请求时,无法正常输出
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="../js/promise.js" type="text/javascript" charset="utf-8"></script></head><body></body><script type="text/javascript">let p =new Promise((resolve,reject)=>{setTimeout(()=>{resolve('ee')},1000)})p.then(data=>{console.log(data)},err=>{console.warn(err)})console.log(p)</script>
</html>
在promise.js 中
//声明一个属性,保存回调this.callback={}
//resolve 函数中添加
//调用成功的回调函数if(self.callback.onResolved){self.callback.onResolved(data);}
//在then方法中添加
//针对使用类似于setTimeout 方法的异步任务 if(this.PromiseState === 'pending'){// 保存回调函数this.callback={onResolved,onRejected}}
指定多个回调函数
let p =new Promise((resolve,reject)=>{setTimeout(()=>{resolve('ee111')},1000)})p.then(data=>{console.log(data+'111')},err=>{console.warn(err)})p.then(data=>{console.log(data+'')},err=>{})p.then(data=>{console.log(data+'')},err=>{})console.log(p)
Promise.prototype.then= function(onResolved,onRejected){//调用回调函数 if(this.PromiseState === 'resolved'){onResolved(this.PromiseResult);}if(this.PromiseState === 'rejected'){onRejected(this.PromiseResult);}//针对使用类似于setTimeout 方法的异步任务 if(this.PromiseState === 'pending'){// 保存回调函数this.callbacks.push({onResolved,onRejected})}
}
//调用成功的回调函数self.callbacks.forEach(item=>{item.onResolved(data);})
同步任务 then 返回结果
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="../js/promise.js" type="text/javascript" charset="utf-8"></script></head><body></body><script type="text/javascript">let p =new Promise((resolve,reject)=>{resolve('ee111')})let result =p.then(data=>{//console.log(data)},err=>{console.warn(err)})console.log(result)</script>
</html>
上面这个问题要怎么处理呢?
//调用回调函数
Promise.prototype.then = function(onResolved, onRejected) {return new Promise((resolve, reject) => {//调用回调函数 if (this.PromiseState === 'resolved') {try{let result = onResolved(this.PromiseResult);if (result instanceof Promise) {// 如果是result.then(v => {resolve(v)}, r => {reject(r)})} else {//结果的对象状态为成功resolve(result)}}catch(e){reject(e)}}if (this.PromiseState === 'rejected') {onRejected(this.PromiseResult);}//针对使用类似于setTimeout 方法的异步任务 if (this.PromiseState === 'pending') {// 保存回调函数this.callbacks.push({onResolved,onRejected})}})
}
异步任务then 返回结果
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="../js/promise.js" type="text/javascript" charset="utf-8"></script></head><body></body><script type="text/javascript">let p =new Promise((resolve,reject)=>{setTimeout(()=>{resolve('ee111')},1000)})let result =p.then(data=>{console.log(data)return 'hello'},err=>{console.warn(err)})console.log(result)</script>
</html>
//针对使用类似于setTimeout 方法的异步任务 if (this.PromiseState === 'pending') {// 保存回调函数this.callbacks.push({onResolved: function() {try {let result = onResolved(self.PromiseResult)if (result instanceof Promise) {result.then(v => {resolve(v);}, r => {reject(r);})} else {resolve(result);}} catch (error) {//TODO handle the exceptionreject(error);}},onRejected: function() {try {let result = onRejected(self.PromiseResult)if (result instanceof Promise) {result.then(v => {resolve(v);}, r => {reject(r);})} else {reject(result);}} catch (error) {//TODO handle the exceptionreject(error);}}})}
catch 方法与异常穿透
Promise.prototype.catch =function(onRejected){return this.then(undefined,onRejected)
}