promise me,一定要学会手写一个Promise(一)

Promise的介绍

1. Promise的介绍

Promise是es6引入的异步编程的解决方法,从语法上说,Promise就是一个构造函数。从功能上说,Promise就是封装了一个异步操作,并可以获取其成功或失败的结果。

2. 常见的异步操作
  1. fs文件读取:require(“fs”).readFile(‘index.html’,(err,data)=>{})
  2. 数据库操作
  3. ajax请求:$.get(url,()=>{})
  4. setTimeout(()=>{},time)
  5. setInterval(()=>{},time)
3. Promise的优势:
  1. 指定回调函数的方式更加灵活
    - 旧:必须在启动异步任务前指定
    - promise:启动异步任务->返回promise对象-给promise对象绑定指定回调函数(甚至可以在异步任务结束后指定多个)
  2. 支持链式调用,可以解决回调地狱问题
    - 回调地狱:回调函数嵌套使用,外部回调函数异步执行的结果是嵌套的回调执行的条件
    - 不便于阅读、不便于异常处理。
    - 可以通过promise链式调用解决。
    -
4. Promise对象
const promise = new Promise((resolve,reject)=>{
	console.log(111)
});
console.log(promise);
/*
Promise {<pending>}
	[[Prototype]]: Promise
	[[PromiseState]]: "pending"
	[[PromiseResult]]: undefined
*/
  1. promise的状态
  • 实例对象中的一个属性,【PromiseState】
  • pending—未决定的
  • resolved/fullfilled—成功
  • rejected—失败
  • 状态只能从pending变为resolved/rejected,不能从resolved->rejected,rejected->resolved
  • 状态只能改变一次
  1. promise 对象的值
  • 实例对象中的另一个属性,【PromiseResult】,保存着对象[成功/失败]的结果。
  • resolve
  • reject
5. promise的工作流程
  • 通过new Promise()创建一个promise对象,在promise内部封装异步操作。
  • 如果异步操作成功,则调用resolve方法,并将promise的状态设置为resolved,并调用then()的第一个回调。返回一个新的promise对象。
  • 如果异步操作失败,则调用reject方法,并将promise的状态设置为rejected,并调用then()的第二个回调。返回一个新的promise对象。
6. promise的API
let p = new Promise((resolve,reject)=>{
      console.log(111);
})
 console.log(222);
 ---先输出111后输出222
  • Promise的构造函数:Promise(executor),
    ----executor函数:(resolve,reject)=>{@}
    ----resolve为成功的回调,reject为失败的回调
    ----executor会在Promise内部立即同步执行,异步操作在执行器中执行。
  • Promise.prototype.then((onResolved,onReject)=>{}),分别是成功和失败的回调
  • Promise.prototype.catch(reson=>{}):失败的回调
  • Promise.resolve方法:(value)=>{},返回成功/失败的promise对象
  • Promise.reject方法:返回一个失败的promise对象
  • Promise.all:(promises)=>{},参数是一个数组,只有所有promise都成功才成功。只要有一个失败了就直接失败。
  • Promise.race:(promises)=>{},参数是一个数组,第一个promise的状态绝对最后结果。
7. promise的几个关键问题
  • 指定回调的方法 then() 或 catch()
  • 修改对象的状态,调用resolve() 或 reject() 或 throw
  let promise = new Promise((resolve,reject)=>{resolve('ok')})
  let promise = new Promise((resolve,reject)=>{reject('fail')})
  let promise = new Promise((resolve,reject)=>{throw 'error'})
  • 能否执行多个回调:当promise改为对应状态时,都会调用
 let promise = new Promise((resolve,reject)=>{
 	reject('ok')
 })
 promise.then((resolve)=>{	
 	console.log("执行了-1")
 }).then((resolve)=>{
 	console.log("执行了-2")
 });
 // 先输出"执行了-1",然后输出"执行了-2"
  • 指定回调与改变状态的执行顺序
    – 改变状态和指定回调的执行顺序,谁先谁后?
    答:都有可能,正常情况是先指定回调函数在改变状态,但是也可以先改变状态再指定回调

– 如何先改变状态再指定回调?

  1. 在执行器中直接调用resolve()/reject()
  2. 延长更长时间才调用then()

– 什么时候才得到数据?

  1. 如果先指定回调,当状态改变时,回调函数就会被调用,得到数据
  2. 如果先改变状态,那当指定回调时,回调函数就会被调用,得到数据
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴为您提供一个手写Promise 实现,代码如下: class Promise { constructor(executor) { this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onResolvedCallbacks.forEach((fn) => fn()); } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach((fn) => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason }; const promise2 = new Promise((resolve, reject) => { if (this.state === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.state === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.state === 'pending') { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); return promise2; } static resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise')); } let called = false; if (x instanceof Promise) { x.then((value) => { Promise.resolvePromise(promise2, value, resolve, reject); }, reject); } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) { try { const then = x.then; if (typeof then === 'function') { then.call(x, (value) => { if (called) return; called = true; Promise.resolvePromise(promise2, value, resolve, reject); }, (reason) => { if (called) return; called = true; reject(reason); }); } else { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值