promise异步 await 事件循环 微任务

开课吧04期03

解决JS单线程的阻塞问题HTML5提出Web Worker标准,允许创建多个线程

同步异步是一种消息通知机制

  • 同步可以理解成非阻塞(相当于并行),异步理解成阻塞(相当于串行),但不绝对
  • 同步while(1)就阻塞了
  • 异步会有回调函数或者返回值通知,不会等待,会去做其他事
  • 同调就是「当发生 A 事件的时候调用 fA () 函数
  • 任务队列中的都是已经完成的异步操作,而不是注册一个异步任务就会被放在任务队列中

关于同步、异步、回调 这篇很清楚:回调(callback)_zjpp2580369的博客-CSDN博客_回调

关于宏任务、微任务:掘金

如何理解process.nextTick()强大的异步专家process.nextTick() - 简书

process.nextTick()比setTimeout()更精准的延迟调用

同步

三个1000的setTimeout会同时执行

alert()会阻塞其他打印

异步

setTimeout中的回调函数、递归

解决 打印222在setTimeout之后的问题

function fn(cb){

        setTimeout(()=>{

                console.log("111");

                cb && cb();

        },1000)

}

fn(function(){

        console.log("222")。

})

解决同步异步不是同一个线程 无法从主线程获取异步的问题

https://www.jb51.net/article/173306.htm

Promise实例化有三种状态:

pending,resolve,reject    执行中,成功时,失败时

默认 pending(没有结果前的状态)

参数 resolve:fulfilled(火狐),reject

两个参数都是调用后出现


Promise提供then方法

then 两个参数(onresolved,onrejected)

let p = new Promise((resolve,reject)=>{

        setTimeout(()=>{

                resolve(“success”);

                // reject(“error”);      两者只能有一个

        },1000);

}

p.then(function(res){          //第一个参数 onresolved

        console.log("成功“,res);

},function(err){                    //第二个参数 onrejected,可省略

        console.log("失败",err);

})


then的三种返回值:

 1、then的回调   无返还时:默认返还resolved状态的promise对象

let p2 = p.then(function(){ } )    

默认返回对象,出现链式,仍可调用then

p2.then();

 2、then的回调  有返还时:返还的是非promise对象,默认还是promise对象   传参

let p2 = p.then(function(){

        console.log(111);

} ) 

console.log(p2); 

let p2 = p.then(function(){

        console.log(111);

} ) . then(function(res){       //拿上面的参数

        console.log(res);         //返回111

} )

 3、直接return Promise对象

let p2 = p.then(function(){

        return new Promise((resolve)=>{

                resolve();

        });         

} )

总结:三种返还的都是promise对象,可以一直调用then

请求图片  实现异步的三种方法:function回调、then、async

 图片加载就是一个异步过程

 

Image是类,分别打印成功和失败


异步实现

 Promise实现

 .then().catch().then  链式操作更便于维护

catch有返还值,返还值参照then方法 


 ES7 async await 异步的同步写法(实现异步操作的同步化

比如登录时,我们必须要在后台返回匹配成功的信息之后才能进行页面跳转

  • async是Promise的语法糖
  • 函数有等待时用await   
  • await后一定要加Promise     等待的标志:resolve
async function fn(){
    await new Promise((reslove,reject)=>{        //await后面必须跟Promise
        
    })
}
fn();

 

 仍然按顺序走,执行resolve才执行下一个

视频中使用方块运动的例子:

     async function fn() {
        try {
            await move(ele, "left", 200);
            await move(ele, "top", 200);
            await move(ele, "left", 0);
            let res = await move(ele, "top", 0);
            console.log(res);
        } catch (err) {
            console.log(err);
        }
    }
    fn();

 try catch  报错并不会阻止程序执行,只是打印出来


finally,catch六.Promise中finally,catch方法的实现 - 知乎

Promise的静态方法:resolve()、reject()、all()和race()五.Promise中静态方法的实现 - 知乎

Promise.resolve()    返还一个状态为resolve的Promise对象

Promise.reject()


 同时执行all(常问)

Promise.all( [p1,p2,p3]).then(  res=> console.log(res)  )        //返回数组,有一个reject时报错

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('p1'), 100)
})
 
 
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => reject('p2'), 500)
})
 
Promise.all([p1, p2]).then(rets => {
   console.log(rets)
})

不管resolve还是reject都执行,但是按照时间先后顺序执行  谁执行的快就拿谁race(常问)

Promise.race( [p1,p2,p3]).then(  res=> console.log(res)  )  

var p1 = new Promise(function(resolve) {
  setTimeout(() => {
    resolve("fulfilled");
  }, 200);
});
var p2 = new Promise(function(resolve, reject) {
  setTimeout(() => {
    reject("rejected");
  }, 100);
});
Promise.race([p1, p2]).catch(function (reason) {
  console.log(reason);      //"rejected"
});

 ES6躬行记(23)——Promise的静态方法和应用 - 知乎

异步异常处理:promise异步异常处理----async和await_Dean's-CSDN博客

对于方法async fn中出现的异步异常,不能用普通的try…catch…方法捕捉到异常,需要这样做:

  1. 把抛出异步异常的方法用promise包裹
  2. await获取fn的返回值: await fn()await作用是计算表达式
  3. try...catch捕获异常
async function fn() {
    try {
        console.log(await fn2())
    } catch(error) {
        console.log('error')
    }
}
async function fn2() {
    await setTimeout(() => {
        throw new Error('error')
    }, 1000)
}

fn()中捕捉不到error,用promise包装一下:

async function fn() {
    try {
        console.log(await fn2())
    } catch(error) {
        console.log('error')
    }
}
function fn2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('error')
        }, 1000)
    })
}

promise为reject时候,捕捉到异常

async await原理是什么?

原理是迭代

迭代协议:规定迭代与实现的逻辑

迭代器:具体的迭代实现逻辑(实现迭代协议)

数组内部有迭代器iterator

  

迭代对象:可被迭代对象(实现迭代器的对象)       数组

迭代语句

for ... in

for ... of (obj不是可迭代对象)


方法实现for ... of迭代对象:(固定写法

let obj = { a:1,b:2,c:3};

obj [Symbol.iterator]  =  function( ){             //iterator方法返回值必须是对象

        //迭代协议 可自定义

        // let value = Object.value(obj);

        let keys = Object.keys(obj);

        let index = 0;

        return{

                next(){

                        if(index >= keys.length){

                                return {

                                        done: true   }

                        }else{

                                return{

                                       done:false,

                                       //value: values [ index++ ]  }         //是否迭代完成

                                       value: {  key: keys [ index ] ,   

                                                     value: obj [ key [ index++ ] ]    }

                        }

                }

        }

}

for(let val of obj){                        //相当于 obj [Symbol.iterator] ().next

        console.log(val);

}


 Generator 是 async await的前身(已经不用了)

function*fn( ){          // Generator函数固定写法

        yield new Promise((resolve, reject)=>{              //yield定义next方法

                setTimeout(()=>{

                        resolve(1);

                }, 500)

        });           

        yield new Promise((resolve, reject)=>{              //yield定义next方法

                setTimeout(()=>{

                        resolve(2);

                }, 500)

        });     

        yield 3;                 //yield 1 2 3 可以直接for ... of调用  

}

co( fn );
co( fn ){                        //处理异步时封装

        let f = fn(); 

        next();             //第一次没有传参

        function next(data){

                if ( ! f.next.done ){

                        f.next.value.then((info)=>{

                                console.log(info,data);      //info是当前resolve的值,data是上一个的值

                                next(info);

                        })

                } 

        }

}



 EventLoop 事件循环机制掘金

 

 

 主线程形成一个执行栈

 

 

 

 

 new  Promise是同步任务

从promise、process.nextTick、setTimeout出发,谈谈Event Loop中的Job queue_liwusen的博客-CSDN博客_process.nexttick settimeouthttps://www.cnblogs.com/youxin/p/3354924.htmlsetTimeout和setInterval的异同https://www.cnblogs.com/youxin/p/3354924.html从promise、process.nextTick、setTimeout出发,谈谈Event Loop中的Job queue_liwusen的博客-CSDN博客_process.nexttick settimeout

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值