js异步编程

同步异步概念

同步(Synchronous)

  • 代码会阻塞

异步(Asynchronous)

  • 代码不会阻塞,不知道何时收到请求

  • 异步代码没法return返回值

  • 通过回调函数获取返回值,但是会存在回调地狱问题

JS为单线程的语言

回调函数方式接收异步代码的结果

function foo(count, successCallback, failureCallback) {
    // 异步任务
    setTimeout(() => {
        if (count > 0) {
            count++

            // 将成功结果传入回调函数successCallback
            successCallback(count)
        } else {

            failureCallback('count<0')
        }
    }, 3000)
}

foo(99, (res) => {
    console.log('count值为:', res);
}, (err) => {
    console.log('错误提示:', err);
})

//3s后打印
//count值为: 100

Promise方式接收异步代码的结果

function foo(count) {

    return new Promise((resolve, reject) => {
        // 异步任务
        setTimeout(() => {
            if (count > 0) {
                count++
                // 将成功结果传入回调函数resolve
                resolve(count)
            } else {
                reject('count<0')
            }
        }, 3000)
    })
}

foo(-99).then(res => {
    console.log('count值为:', res);
}).catch(err => {
    console.log('错误提示:', err);
})

//3s后打印
//count值为: 100

promise

promise概念

promise为一个对象,存取异步调用的结果

回调函数的嵌套写法,promise将其简化为链式编程

Promise中维护了两个隐藏属性:

  1. PromiseValue,用来存储数据
  2. PromiseStatus,记录Promise的状态
    • pending 进行中
    • fulfilled 完成。执行了resolve回调,触发then回调函数
    • rejected 拒绝。执行了reject回调,触发catch回调函数

resolve/reject传参

resolve(val)

  1. val为基本类型、引用类型

  2. val为新的Promise对象,取决于新的Promise对象

    const newP = new Promise((resolve, reject) => {
        // resolve('newP resolved')
        reject('newP rejected')
    })
    
    const p = new Promise((resolve, reject) => {
        resolve(newP)
    })
    
    p.then(res => {
        console.log(res);
    }).catch(err => {
        console.log(err);
    })
    
    //newP rejected
    
  3. val为thenable,取决于then的回调函数

    const p = new Promise((resolve, reject) => {
        resolve(1)
    })
    
    p.then(res => {
        console.log('then1:', res);
        return {
            then: function (resolve) {
                resolve(2)
            }
        }
    }).then(res => {
        console.log('then2:', res);
    })
    
    //then1: 1
    //then2: 2
    

reject(val)

val任意类型,都会直接传递到catch

then/catch执行时机

创建promise对象后,自动调用回调函数(resolve, reject)=>{}

每个then catch方法都返回promise对象

  1. 手动return、抛出异常 返回结果分别被链式中最近的then、catch拿到

  2. 没有手动return、抛出异常 返回undefined

const p = new Promise((resolve, reject) => {
    resolve(1)
})

p.then(res => {
    console.log('then1:', res);
}).then(res => {
    console.log('then2:', res);
    return 2
}).catch(err => {
    console.log('catch1:', err);
}).then(res => {
    console.log('then3:', res);
    throw new Error('出错了')
}).catch(err => {
    console.log('catch2:', err);
})

p.then(res => {
    console.log('then11:', res);
})

//结果
then1: 1
then11: 1
then2: undefined
then3: 2
catch2: Error: 出错了
// 创建promise对象后,自动调用回调函数
const promise = new Promise((resolve, reject) => {
    // resolve('111')
    reject('111')

})

// 第一个回调函数取出
promise.then((result) => {
    console.log(result);
}, (reason) => {
    console.log(reason);
})

promise.catch((reason) => {
    console.log(reason);
})

promise.finally(() => {
    console.log("成功与否都他妈执行");
})
Promise.resolve().then(() => { //Promise.resolve()返回resolved状态,触发then回调
    console.log(1);  //打印1 返回resolved转态,触发then回调
}).catch(() => {
    console.log(2);
}).then(() => {  // 打印3 整体返回resolved状态
    console.log(3);
})

//1
//3
Promise.resolve().then(() => { //打印1 返回rejected状态 触发catch回调
    console.log(1);
    throw new Error('erro1')
}).catch(() => { //打印2 返回resolved状态 触发then回调
    console.log(2);
}).catch(() => {
    console.log(3);
})

//1
//2
//sum返回一个promise对象,则sum为异步函数
function sum(a, b) {

    // promise处理异步代码
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a + b)
        }, 1000);
    })
}

// promise解决回调地狱的方式
// promise对象调用then catch finally方法都会返回promise对象
sum(1, 2)
	//第一个then拿到sum中promise对象的resolve存储的值
    .then(result => {
        return result + 3
    //第二个then上一个then的返回值
    }).then(result => {
        return result + 4
    }).then(result => {
        console.log(result);
    })

//输出
//10

Promise静态方法

//1.将Promise对象设置为fulfilled
Promise.resolve() 


//2.将Promise对象设置为rejected
Promise.reject() 


//3.then所有Promise对象都为fulfilled
//  catch最快的rejected状态
//输出:[val1,val2,...]
Promise.all([p1,p2,...]) 

             
//4.then所有Promise对象都有状态(不论状态fulfilled/rejected)
//输出:对象数组
Promise.allSettled([p1,p2,...]) 


//5.then最快的fulfilled状态
//  catch最快的rejected状态
// 注:fulfilled、rejected状态一起比
Promise.race([p1,p2,...]) 
   
              
//6.then最快的fulfilled状态
//  catch所有Promise对象都为rejected状态
// 注:fulfilled状态一起比
Promise.any([p1,p2,...]) 

宏任务微任务

微任务队列:Promise、async/await、Object.observe、Proxy

  • new Promise((resolve, reject) => {…})

    new Promise的回调函数(resolve, reject) => {…}是同步的立即执行

    then catch finally方法的回调函数进入微任务队列

  • await下面的代码相当于then回调里的代码,放入微任务队列

宏任务队列:定时器,延时器,Ajax,浏览器帧循环requestAnimationFrame

  • setTimeout(fn,t),时间t之后回调函数fn进入宏任务队列

执行流程(执行每一个宏任务之前都先执行完微任务队列)

  1. 调用栈(主线程)中的代码
  2. 微任务队列的所有任务
  3. DOM监听、UI渲染
  4. 宏任务队列的所有任务

async与await

以同步的方式,书写异步代码

  1. async函数返回值
    • 普通值,包裹到Promise.resolve中
    • 新的Promise,状态由新Promise决定
    • thenable,状态由返回对象的then方法决定
  2. await只能用于 async声明的异步函数中,或es模块的顶级作用域中
  3. await下面的代码相当于then回调里的代码,放入微任务队列
async function fn(){
    // async函数返回promise对象
    // 100 会包装为promise对象
    return 100
}

(async function(){
    const a = fn()
    // Promise {<fulfilled>: 100}
    console.log(a);
	
    // await下面的代码相当于then回调里的代码
    const b = await fn()
    // 100
    console.log(b);
})()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值