Promise

Promise


为了解决回调地狱,就要使用 promise 语法

语法:

new Promise(function (resolve, reject) {
  // resolve 表示成功的回调
  // reject 表示失败的回调
}).then(function (res) {
  // 成功的函数
}).catch(function (err) {
  // 失败的函数
})

每一个异步事件,在执行的时候都会有三个状态,执行中 / 成功 / 失败,

因为它包含了成功的回调函数

所以我们就可以使用 promise 来解决多个 ajax 发送的问题

new Promise(function (resolve, reject) {
  ajax({
    url: '第一个请求',
    success (res) {
      resolve(res)
    }
  })
}).then(function (res) {
  // 准备发送第二个请求
  return new Promise(function (resolve, reject) {
    ajax({
      url: '第二个请求',
      data: { a: res.a, b: res.b },
      success (res) {
        resolve(res)
      }
    })
  })
}).then(function (res) {
  ajax({
    url: '第三个请求',
    data: { a: res.a, b: res.b },
    success (res) {
      console.log(res)
    }
  })
})

Promise的任务队列为微任务队列,优先级高于宏任务队列,次于同步队列,会在事件循环之后执行

当Promise赋值变量传递给另一个Promise的reslove()时,状态会进行传递

Promise状态不可逆,Promise传递了状态 then才会执行否则会一直等待,Promise写两个状态只执行第一个,一旦确定了状态就不能修改

then、catch也是一个Promise,是对上一个Promise的结果处理,then、catch默认返回结果是成功,

then如果return的是一个值那下一个then就能相应接收,如果then返回的是一个new Promise,那下一个then就是对这个返回的new Promise的状态处理(没有状态则下一个then一直等待)

then如果return的也是then,那这个返回出来的then可以封装为Promise,跟Promise性质一样

catch

Promise内会进行错误处理,没有改变Promise的状态下,throw new Error(“fail”)或hd+1(hd未定义等其他错误) 都会判断为reject进行处理同时执行处理错误的回调函数。

这个错误也可以使用.catch()进行捕获,会捕获之前所有then的错误 所以可以在前面的then省略错误处理回调,在Promise的最后添加.catch(()=>{})统一进行错误处理

finally

写在Promise的最后不管状态成功失败都会执行.finally(()=>{})

reslove

Promise.reslove() 直接为成功状态

reject

Promise.reject() 直接为失败状态,也可以通过抛异常的方式改变单次Promise的状态

all
Promise.all([第一个Promise,第二个Promise]) .then()
如果前面的Promise都为成功状态才会执行Promise.all的then下的成功回调

allSettled
Promise.allSettled([第一个Promise,第二个Promise]) .then()
会把前面成功跟失败的promise全部收集起来,Promise.allSettled的状态始终是成功状态

race
Promise.race([第一个Promise,第二个Promise]) .then()
比较几个Promise那个先执行完 ,then获取那个Promise的reslove(“获取值”)



// 手写promise

class MyPromise {
  constructor(executor) {
    this.status = 'pending' // 初始状态为等待
    this.value = null // 成功的值
    this.reason = null // 失败的原因
    this.onFulfilledCallbacks = [] // 成功的回调函数数组
    this.onRejectedCallbacks = [] // 失败的回调函数数组
    let resolve = value => {
      if (this.status === 'pending') {
        this.status = 'fulfilled'
        this.value = value;
        this.onFulfilledCallbacks.forEach(fn => fn()) // 调用成功的回调函数
      }
    }
    let reject = reason => {
      if (this.status === 'pending') {
        this.status = 'rejected'
        this.reason = reason
        this.onRejectedCallbacks.forEach(fn => fn()) // 调用失败的回调函数
      }
    };
    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }
  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      if (this.status === 'fulfilled') {
        setTimeout(() => {
          const x = onFulfilled(this.value);
          x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
        })
      }
      if (this.status === 'rejected') {
        setTimeout(() => {
          const x = onRejected(this.reason)
          x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
        })
      }
      if (this.status === 'pending') {
        this.onFulfilledCallbacks.push(() => { // 将成功的回调函数放入成功数组
          setTimeout(() => {
            const x = onFulfilled(this.value)
            x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
          })
        })
        this.onRejectedCallbacks.push(() => { // 将失败的回调函数放入失败数组
          setTimeout(() => {
            const x = onRejected(this.reason)
            x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
          })
        })
      }
    })
  }
}

// 测试
function p1() {
  return new MyPromise((resolve, reject) => {
    setTimeout(resolve, 1000, 1)
  })
}
function p2() {
  return new MyPromise((resolve, reject) => {
    setTimeout(resolve, 1000, 2)
  })
}
p1().then(res => {
  console.log(res) // 1
  return p2()
}).then(ret => {
  console.log(ret) // 2
})



Async/Await


async/await 是一个 es7 的语法,是 回调地狱的终极解决方案

语法:

async function fn() {
  const res = await promise对象
}

await 一个 promise 对象,可以把异步代码写的看起来像同步代码

await会将后面代码挂起 等待await后面的promise返回状态 这个称为协程

只要是一个 promiser 对象,那么就可以使用 async/await 来书写

async function fn() {
  const res = new Promise(function (resolve, reject) {
    ajax({
      url: '第一个地址',
      success (res) {
        resolve(res)
      }
    })
  })
  
  // res 就可以得到请求的结果
  const res2 = new Promise(function (resolve, reject) {
    ajax({
      url: '第二个地址',
      data: { a: res.a, b: res.b },
      success (res) {
        resolve(res)
      }
    })
  })
  
  const res3 = new Promise(function (resolve, reject) {
    ajax({
      url: '第三个地址',
      data: { a: res2.a, b: res2.b },
      success (res) {
        resolve(res)
      }
    })
  })
  
  // res3 就是我们要的结果
  console.log(res3)
}

注:
async中没有await就是同步代码

async中有await就是异步代码

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Raccom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值