异步

一、ES5有关异步的处理方式

A回调B,B回调C....
使用回调函数处理,会造成“回调地狱”,维护困难

function fn1(val, callback) {
    console.log(val)
    if (a > 10 && typeof fn2 == 'function') {
        callback()
    }
}
fn1(11, function() {
    console.log('this is a callback')
})

二、ES6使用promise改变ES5的回调地狱问题

2-1状态

  • pending 等待状态
  • fulfiled 成功状态
  • rejected 失败
class Promise {
    constructor (executor){
        //默认状态是等待状态
        this.status = 'pending';
        this.value = undefined;
        this.reason = undefined;
        //存放成功的回调
        this.onResolvedCallbacks = [];
        //存放失败的回调
        this.onRejectedCallbacks = [];
        let resolve = (data) => {//this指的是实例
            if(this.status === 'pending'){
                this.value = data;
                this.status = "fulfiled";
                this.onResolvedCallbacks.forEach(fn => fn());
            }
 
        }
        let reject = (reason) => {
            if(this.status === 'pending'){
                this.reason = reason;
                this.status = 'rejected';
                this.onRejectedCallbacks.forEach(fn => fn());
            }
        }
        try{//执行时可能会发生异常
            executor(resolve,reject);
        }catch (e){
            reject(e);//promise失败了
        }
    }

2-2promise用法

基本用法

function p (val){ 
  // pending undefined
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      if(val>5){
        resolve(console.log('成功的回调')); // fulfilled,result
      }else{
        reject(console.log('失败的回调')); // rejected, error
      }
    },1000)
  })
}
p(6).then(res=>{
  console.log(res)
}) // 结果为成功的回调

then的链式调用

p(10)
  .then(()=>{
    p(2);
  })
  .then(()=>{
     p(3)
  })
  .then(()=>{
     p(8)
  })
打印结果为:成功的回调 失败的回调 失败的回调 成功的回调
// then是promise对象原型链的方法,参数有2个,是函数,then(onFulFilled, onRejected);
// 当参数不是函数时,则返回空的promise对象,则可继续使用then,当返回的是空的promise对象时,
// 即可解释当回调失败的时候,可以继续向下执行;如果不希望如此,可以在前面添加return

All的用法

处理情景:当需要3个接口返回数据之后,在做操作时使用,并行处理

const p1 = Promise.resolve(1)
const p2 = Promise.resolve(20)
const p3 = Promise.resolve(3)

Promise.all([p1, p2, p3]).then((value) => {
   console.log(value); // 结果为1 20 3
})

race的用法

处理情景:静态资源的返回,哪个cdn返回更快

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

const p2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve(2)
    }, 3000)
  })
}

Promise.race([p1(), p2()]).then((value) => {
  console.log(value)
}) // 返回结果为1

catch用来捕捉错误

三、ES8使用async await,其实是promise的语法糖

async function f() {
    return 'hello world'
};
f().then( (v) => console.log(v)) // hello world 函数前添加async会return出promise的对象

const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout));
async function f(){
    await delay(1000);
    await delay(2000);
    await delay(3000);
    return 'done';
}

f().then(v => console.log(v)); 
// 等待6s后才输出 'done'复制代码正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolve 的 Promise

四、有关promise的面试题

https://juejin.im/post/5b31a4b7f265da595725f322
https://juejin.im/post/5a04066351882517c416715d
https://juejin.im/post/5af800fe518825429c594f92
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一、Javascript实现异步编程的过程以及原理 1、为什么要用Javascript异步编程 众所周知,Java...
    Ebony_7c03阅读 4,310评论 0 2
  • 弄懂js异步 讲异步之前,我们必须掌握一个基础知识-event-loop。 我们知道JavaScript的一大特点...
    DCbryant阅读 7,673评论 0 5
  • JavaScript语言的执行环境是‘单线程’的(也就是说,执行后续的代码之前必须完成前面的任务,也就是采用的是阻...
    kim_jin阅读 3,619评论 0 0
  • 前言 异步编程模式在前端开发过程中,显得越来越重要。从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的...
    浪里行舟阅读 12,733评论 0 7
  • Next comes Nibs, the gay and debonair, followed by Slight...
    Mr_Oldman阅读 2,498评论 0 1

友情链接更多精彩内容