Promise基础

136 阅读4分钟

Promise的基本用法

image.png

image.png

image.png

then()方法

image.png

image.png

image.png

image.png

image.png

image.png

catch()方法

image.png

image.png

image.png

finally()方法

啥也不干,类似中转站

Promise.resolve() 和 Promise.reject()

Promise.resolve()

image.png

image.png

image.png

image.png

image.png

Promise.reject()

image.png

image.png

image.png

Promise.all()

image.png

image.png

Promise.race() 和 Promise.allSettled()

Promise.race()

image.png

image.png

Promise.allSettled()

image.png

Promise的注意事项

image.png

image.png

image.png

image.png

image.png

image.png

Promise的应用

image.png

image.png

image.png

Promise基础总结

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

Promise二次封装axios

为什么二次封装axios? 可以集中对请求和响应做处理。

另外,跨域问题一般在开发环境中出现,生产环境都用的同一域门不存在跨域;

Promise

基础

优点

1.指定回调函数的方式更加灵活; 2.支持链式调用,可以解决回调地狱问题.

案例

Demo1

function rand() {
    return Math.ceil(Math.random()*(n-m+1)) + m-1
}

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        let n = rand(1, 100)
        if (n <= 30) {
            resolve(n)
        } else {
            reject(n)
        }
    }, 1000)
})

p.then((res) => {
    alert('恭喜恭喜,奖品为 10万 RMB 劳斯莱斯优惠券, 您的号码为:' + res)
}, (err) => {
    alert('再接再厉, 您的号码为:' + err)
})

Demo2 fs文件操作

const fs = require('fs')

const p = new Promise((resolve, reject) => {
    fs.readFile('./resource/content.txt', (err, data) => {
        // if(err) throw err
        // console.log(data)
        if(err) reject(err)
        resolve(data)
    })
})

p.then(res => {
    console.log(res.toString())
}, (err) => {
    console.log(err)
})

最后,可在终端运行命令查看结果:node demo.js

Demo3 Promise封装 fs

function mineReadFile(path) {
  return new Promise((resolve, reject) => {
      require('fs').readFile(path, (err, data) => {
        if(err) reject(err)
        resolve(data)
      })
  })
}

mineReadFile('./resource/content.txt').then(res => {
    console.log(res.toString())
}, err => {
    console.error(err)
})

Demo4 util.promisify方法进行Promise转化

const util = require('util')
const fs = require('fs')
let mineReadFile = util.promisify(fs.readFile) // 返回一个新的函数
mineReadFile('./resource/content.txt').then(res => {
    console.log(res.toString())
}, err => {
    console.error(err)
})

Promise实例对象结果值属性

const p = new Promise() // 构造函数 得到 实例化对象Promise {} console.log(p) 输出结果: Promise { [PromiseState]: 'rejected' [PromiseResult]: 52 }

Promise的状态

实例对象中的一个属性 [PromiseState] pending 未决定的 resolved / fullfilled 成功 rejected 失败

状态改变: pending -> resolved 或 pending -> rejected

Promise 对象的值

实例对象中的另一个属性 [PromiseResult] 保存着对象[成功/失败]的结果 resolve reject

API

  1. Promise构造函数:Promise(executor) {} ①executor函数:执行器 (resolve, reject) => {} ②resolve函数:内部定义成功时调用的函数 res => {} ③reject函数:内部定义失败时调用的函数 err => {} **executor会在Promise内部立即同步调用,异步操作在执行器中执行

  2. Promise.prototype.then方法:(onResolved, onRejected) => {} ①onResolved函数:成功的回调函数 res => {} ②onRejected函数:失败的回调函数 err => {}

  3. Promise.prototype.catch方法:(onRejected) => {} ①onRejected函数:失败的回调函数 err => {}

  4. Promise.resolve(value) **value:成功的数据或promise对象。返回一个成功的promise对象。

  5. Promise.reject(reason) **reason:失败的原因。返回一个失败的promise对象。

  6. Promise.all(promises:[])

let p1 = new Promise((resolve, reject) => {
    resolve('OK')
})
let p2 = Promise.resolve('Success')
let p3 = Promise.resolve('Oh Yeah')
const result = Promise.all([p1, p2, p3])
console.log(result)

** 返回一个新的promise, 只有所有的promise都成功才成功,只要有一个失败了就直接失败

  1. Promise.race(promises:[])
let p1 = new Promise((resolve, reject) => {
    resolve('OK')
})
let p2 = Promise.resolve('Success')
let p3 = Promise.resolve('Oh Yeah')
const result = Promise.race([p1, p2, p3])
console.log(result)

** 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态

Promise的关键问题

Promise对象改变状态的方式

let p = new Promise((resolve, reject) => {
    // 1. resolve 函数
    resolve('OK')  // pending => fulfilled (resolved)
    // 2. reject 函数
    reject('error')  // pending => rejected
    // 3. 抛出错误
    throw '出问题了'
})
console.log(p)

能否执行多个回调

** 当promise改变为对应状态时都会调用

let p = new Promise((resolve, reject) => {
    resolve('OK')
})
// 指定回调 1
p.then(res => {
    console.log(res)
})
// 指定回调 2
p.then(res => {
    alert(res)
})

改变promise状态和指定回调谁先执行

  1. 都有可能,正常情况是先指定回调再改变状态,但也可以先改状态再指定回调
  2. 先改状态再指定回调:①在执行器中直接调用resolve()/reject() ②延迟更长时间才调用then()
  3. 什么时候拿到数据:①如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据;②如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据

promise.then()返回的新promise的结果状态由什么决定?

由then()指定的回调函数执行的结果决定

let p = new Promise((resolve, reject) => {
    resolve('ok')
})
let result = p.then(value => {
    // console.log(value)
    1. 抛出错误
    throw '出了问题' // result 返回失败的promise对象
    2. 返回结果是非Promise类型的对象
    return 521      // result 返回成功的promise对象
    3. 返回结果是promise对象
    return new Promise((resolve, reject) => {
        resolve('success')  // result 返回成功的promise对象
        reject('error')     // result 返回失败的promise对象
    })
}, reason => {
    console.warn(reason)
})
console.log(result)

①如果抛出异常,新promise变为rejected,reason为抛出的异常 ②如果返回的是非promise的任意值,新promise变为resolved,value为返回的值 ③如果返回的是另一个新promise,此promise的结果就会成为新promise的结果

promise如何串连多个操作任务

  1. promise的then()返回一个新的promise,可以看成then()的链式调用
  2. 通过then的链式调用串连多个同步/异步任务

promise异常传透

  1. 当使用promise的then链式调用时,可以在最后指定失败的回调
  2. 前面任何操作出了异常,都会传到最后失败的回调中处理

手写Promise Promise的封装

......

acync 和 await