promise与 fetch、async/await

目录

promise应用:webpack loader

promise手写

Promise.prototype(实例)方法

均返回promise

then回调函数:

resolveFn的形参=resolve的参数

catch回调函数:

rejectFn的形参=reject的参数

finally回调函数:返回上一次的Promise对象值/promise包装的error

Promise并发方法

allSettled() :多个不依赖于彼此成功完成的异步任务时,或者:想知道每个 promise 的结果时

all:当异步操作之间不存在结果的依赖时,all中的所有方法是一同执行的

race:只保留第一个结果,其他的方法仍在执行

any:其中一个成功结果,都失败则报错

map:promise.reslove(catch)

观察者模式

创建Promise实例

await 值=Promise.resolve(值)

Promise.resolve(值):如果该值本身就是一个 promise实例,将直接被返回

Promise.reject(值)

constructor的函数参数:起始函数;同步(立即执行)

起始函数的函数参数(均可选):resolve (起始函数成功时调用)、reject(失败时调用)

状态:都没有的话,状态为pending[待定]初始状态

fetch es6 api:基于promise,简单易用 

回调函数:参数为函数,且满足条件才执行该参数函数

隐式return 原promise对象/ 显式return (非promise会包装成promise)

then/catch/finally/async

async/await函数

async关键字+函数

await 操作符+promise对象

promise对象变成reject状态时,整个async函数会中断

处理异常: try-catch 块

promise应用:webpack loader

promise手写

Promise.prototype(实例)方法

均返回promise

then回调函数:

resolveFn的形参=resolve的参数

catch回调函数:

rejectFn的形参=reject的参数
promise.then(f1).catch(f2);
//f1 和 f2处于同一层级,二者只会执行其一,下面没有链,所以 error 不会被处理。
promise.then(f1, f2);

异常穿透:错误的传递(就近的 onRejected /catch)

一遇到异常抛出,浏览器就会顺着 Promise 链寻找下一个就近的 onRejected 失败回调函数或者由 .catch() 指定的回调函数。

new Promise((resolve, reject) => {
    reject('失败了')
})
    .then(
        (data) => { console.log('onResolved1', data); },
        (error) => { console.log('onRejected2', error); }
    )
    .catch(
        (error) => {
            console.log('catch', error)
        }
    )

"失败了" 就会被离它最近的 then 中的 onRejected 函数所处理,而不会被 catch 所捕获。

finally回调函数:返回上一次的Promise对象值/promise包装的error

Promise并发方法

allSettled() :多个不依赖于彼此成功完成的异步任务时,或者:想知道每个 promise 的结果时

all:当异步操作之间不存在结果的依赖时,all中的所有方法是一同执行的

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');//setTimeout(function[, delay, arg1, arg2, ...]);
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// Expected output: Array [3, 42, "foo"]

race:只保留第一个结果,其他的方法仍在执行

any:其中一个成功结果,都失败则报错

map:promise.reslove(catch)

catch方法返回的promise实例会被promise.reslove()包裹,这样传进promise.all的数据都是resolved状态的。

let p1 = Promise.resolve(1)
let p2 = Promise.resolve(2)
let p3 = Promise.resolve(3)
let p4 = Promise.resolve(4)
let p5 = Promise.reject("error")
let arr = [p1,p2,p3,p4,p5];

let all = Promise.all(arr.map((promise)=>promise.catch((e)=>{console.log("错误信息"+e)})))
all.then(res=>{console.log(res)}).catch(err=>console.log(err));

观察者模式

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('result')
    },
    1000);
}) 

p1.then(res => console.log(res), err => console.log(err))

分析Promise的调用流程:

  • Promise的构造方法接收一个executor(),在new Promise()时就立刻执行这个executor回调
  • executor()内部的异步任务被放入宏/微任务队列,等待执行
  • then()被执行,收集成功/失败回调,放入成功/失败队列
  • executor()的异步任务被执行,触发resolve/reject,从成功/失败队列中取出回调依次执行

观察者模式:收集依赖 -> 触发通知 -> 取出依赖执行

在Promise里,执行顺序是then收集依赖 -> 异步触发resolve -> resolve执行依赖

class MyPromise {
  // 构造方法接收一个回调
  constructor(executor) {
    this._resolveQueue = []    // then收集的执行成功的回调队列
    this._rejectQueue = []     // then收集的执行失败的回调队列

    /*由于resolve/reject是在executor内部被调用, 
    因此需要使用箭头函数固定this指向, 否则找不到this._resolveQueue*/

    let _resolve = (val) => {
      // 从成功队列里取出回调依次执行
      while(this._resolveQueue.length) {
        const callback = this._resolveQueue.shift()
        callback(val)
      }
    }
    // 实现同resolve
    let _reject = (val) => {
      while(this._rejectQueue.length) {
        const callback = this._rejectQueue.shift()
        callback(val)
      }
    }
    // new Promise()时立即执行executor,并传入resolve和reject
    executor(_resolve, _reject)
  }

  // then方法,接收一个成功的回调和一个失败的回调,并push进对应队列
  then(resolveFn, rejectFn) {
    this._resolveQueue.push(resolveFn)
    this._rejectQueue.push(rejectFn)
  }
}

创建Promise实例

await 值=Promise.resolve(值)

Promise.resolve(值):如果该值本身就是一个 promise实例,将直接被返回

Promise.reject(值)

constructor的函数参数:起始函数;同步(立即执行)

起始函数的函数参数(均可选):resolve (起始函数成功时调用)、reject(失败时调用

状态:都没有的话,状态为pending[待定]初始状态
//​​什么都不输出​​​​​
new Promise(()=>{}).then(()=>{
  console.log("then")
}).finally(()=>{
  console.log("finally")
})

【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理) - 掘金

错误无法捕获

异步回调中:promise已结束

在延时等待 1s 后,抛出错误这一操作才会执行,但此时外面的 Promise 早就执行结束。

因此,promise 无法处理它,程序会在此崩掉。

new Promise((resolve, reject) => {
    setTimeout(() => {
        throw new Error("Whoops!");
    }, 1000);
})
    .catch(error => {
        console.log('catch error:', error);
    });
//无任何输出

解决executor 中的异步错误:resolve/reject ,便于后续链式调用

new Promise((resolve, reject) => {
    setTimeout(() => {
        try {
            resolve()
        } catch(error) {
            reject(error)
        }
    }, 1000);
})

try…catch: promise 内部的错误不会冒泡 

function fn1() {
    try {
        new Promise((resolve, reject) => {
            throw new Error('promise1 error')
        })
    } catch (error) {
        console.log(e.message);
    }
}

function fn2() {
    try {
        Promise.reject('promise2 error');
    } catch (error) {
        console.log(error);
    }
}

A.then、catch捕获

B.async/await 

// 模拟请求
function http(params) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (params === 0) reject("error")
            resolve("success")
        }, 1000);
    })
}

// 业务调用
async function query(params) {
    try {
        const data = await http(params)
        console.log('data:', data);
    } catch (error) {
        console.log('error:', error);
    }
}

query(0)

中断promise:return pending 的 promise

new Promise(() => {})

.catch((err) => {
  console.log('onRejected', err);
  // 中断promise链:
  return new Promise(() => {})
})

fetch es6 api:基于promise,简单易用 

window.fetch(url, { method: 'get'})   //fetch() 返回响应的promise 
    // 第一个then  设置请求的格式
        .then(res => return res.json())  // 第一层then返回的是:响应的报文对象  
        .then((data) => {             //第二层:如果想要使用第一层的数据,必须把数据序列化  
                                       res.json() 返回的对象是一个 Promise对象再进行then()
         <!-- data为真正数据 -->
    }).catch(e => console.log("Oops, error", e))

回调函数:参数为函数,且满足条件才执行该参数函数

隐式return 原promise对象/ 显式return (非promise会包装成promise)

then/catch/finally/async

async/await函数

Promise.resolve(a)
  .then(b => {
    // do something
  })
  .then(c => {
    // do something
  })

//等价于
async () => {
  const a = await Promise.resolve(a);
  const b = await Promise.resolve(b);
  const c = await Promise.resolve(c);
}

async关键字+函数

await 操作符+promise对象

promise对象变成reject状态时,整个async函数会中断

处理异常: try-catch 块
async function asyncFunc() {
    try {
        await new Promise(function (resolve, reject) {
            throw "Some error"; // 或者 reject("Some error")
        });
    } catch (err) {
        console.log(err);
        // 会输出 Some error
    }
}
asyncFunc();

猜你喜欢

转载自blog.csdn.net/qq_28838891/article/details/134398381