【ES6系列】Promise

Promise 基本用法(Promise Syntax):new Promise( function(resolve, reject) {…} );

通过创建 Promise 对象开启一个异步操作的过程,一般用几步完成多次异步操作:

  1. new Promise(fn) 返回一个Promise 对象
  2. 在fn 中指定异步等处理
  3. 处理结果正常的话,调用resolve(处理结果值)
  4. 处理结果错误的话,调用reject(Error对象)
function loadScript(src) {
  return new Promise((resolve, reject) => {
    let script = document.createElement('script')
    script.src = src
    script.onload = () => resolve(src)
    script.onerror = (err) => reject(err)
    document.head.append(script)
  })
}
loadScript('./1.js')
  .then(loadScript('./2.js'))
  .then(loadScript('./3.js'))

Promise 内部状态(pending、fulfilled、rejected),Promise 对象根据状态来确定执行哪个方法。Promise 在实例化的时候状态默认为 pending,当异步操作完成,状态会被修改为 fulfilled,当异步操作遇到异常,状态会被修改为 rejected。而此种状态变化是单向且不可逆转的,已经确定的状态(fulfilled/rejected)无法转回初始状态(pending),而且只能是从 pending 到 fulfilled 或者 rejected

串行异步操作——Promise.prototype.then():then 是 promise 原型上的方法,只有promise可以调用then

基本语法:promise.then(onFulfilled, onRejected):then 支持两个参数,这两个参数都是函数类型,第一个参数必选,第二个参数可选。这两个函数分别对应是 Promise 对象的resolve 和 reject 这两个方法,如果传入的这两个参数是非函数或被遗漏,会返回一个空的 promise 对象,以保证只要调用 promise 对象就一定可以返回一个 promise 对象,所以可以链式调用 .then()

写法改造:

function loadScript(src) {
  return new Promise((resolve, reject) => {
    let script = document.createElement('script')
    script.src = src
    script.onload = () => resolve(src)
    script.onerror = (err) => reject(err)
    document.head.append(script)
  })
}
loadScript('./1.js')
  .then(() => {
    return loadScript('./4.js') // 返回 promise 对象影响下一个.then()
  }, (err) => {
    console.log(err)
  })
  .then(() => {
    loadScript('./3.js')
  }, (err) => {
    console.log(err)
  })

Promise.resolve() 和 Promise.reject() 是 Promise 的静态方法,是 new Promise() 方法的快捷方式。

Promise.prototype.catch(),用 Promise 对象的 catch 方法来捕获异步操作过程中出现的任何异常,当 promise 状态改为rejected时捕获错误。

 new Error 不会触发 catch,而是 reject,不建议在 Promise 内部使用 throw 来触发异常,而是使用 reject(new Error()) 的方式来做,因为 throw 的方式并没有改变 Promise 的状态

并行异步操作——Promise.all():满足所有任务都完成的条件

生成并返回一个新的 Promise 对象,所以它可以使用 Promise 实例的所有方法。参数传递promise数组中所有的 Promise 对象都变为resolve的时候,该方法才会返回, 新创建的 Promise 则会使用这些 promise 的值。如果参数中的任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的 Promise 对象。由于参数数组中的每个元素都是由 Promise.resolve 包装(wrap)的,所以Paomise.all 可以处理不同类型的 promose对象。

const p1 = Promise.resolve(1) //使用Promise进行一个异步操作,返回结果是1
const p2 = Promise.resolve(2)
const p3 = Promise.resolve(3)
Promise.all([p1, p2, p3]).then((value) => {
  console.log(value) //[1, 2, 3]
})

Promise.race():先到先得

Promise.race 生成并返回一个新的 Promise 对象。参数 promise 数组中的任何一个 Promise 对象如果变为 resolve 或者 reject 的话, 该函数就会返回,并使用这个 Promise 对象的值进行 resolve 或者 reject。

思考:

1、按顺序加载脚本太直观看出顺序执行的过程,如果按顺序延时执行是不是更好理解?

2、请用 Promise 实现一个接口。

const p1 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve(1)
    }, 1000)
  })
}

const p2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve(2)
    }, 0)
  })
}
Promise.race([p1(), p2()]).then((value) => {
  console.log(value) // 2
})

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值