js异步执行的各种方式 | 8月更文挑战

224 阅读3分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

首先,大家都知道js是单线程的,那我们很多方法执行的时候不需要同步,而需要异步,该怎么执行呢?但是单线程基于异步的时候又会怎么样执行呢?浏览器是多线程的,与内核的控制配合保持同步执行,一个浏览器至少实现3个常驻线程:js引擎线程,GUI渲染线程,浏览器事件触发线程(UI线程)。

一、setTimeout实现异步

例如:
let code = 0;function fun1() { 
    //请求接口得到code
}function fun2() { 
    //请求接口用code换取key
}
fun1();
fun2();
//这时候需要fun1先执行,再执行fun2
//可以改为:
fun1();
setTimeout(){=>{fun2();},500}

注:使用setTimeout可能会出现问题,必须第一个方法还没返回,但是因为setTimeout时间到了,就执行了fun2()这时候可能code还没有,就会出现bug,所以不是非常推荐。

二、使用callback回调函数执行

//还是刚刚的方法b体,改为:
let code = 0;
function fun1(callback) { 
    //请求接口得到code,success中调用callback();
    callback();
}
function fun2() { 
    //请求接口用code换取key
}
fun1(fun2());

注:这样不会出现setTimeout发生的问题,但是如果很多方法之间存在关联关系,可能会造成代码连贯性错误,一个方法执行不下去可能整个页面和js代码就执行不下去了。

三、promise对象

promise是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(除闭包)。主要用于异步操作,可以把异步操作队列化。

promise有三种状态:

      pending 等待

      fulfilled 操作成功

      rejected 操作失败

promise从pending状态中转变只能是fulfilled或rejected,且改变后不会再变

let num = 10;
let p1 = new Promise(function(reslove){
    setTimeout(()=> {
        if(num > 10) {
            reslove(20);
        }else {
            reject(new Error('is a bug~'));
        }
    },1000)
})function fun2() { 
    num++;
}p1.then(fun2());//fun1返回一个promise,指定回调函数fun2(),可以执行多个.then();(fun2()最好也是promise对象,这里没有详细写)

Promise.all()批量执行

let numFun = (num) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(num)
    }, 1000)
  })
}

let p1 = numFun(1)
let p2 = numFun(2)

Promise.all([p1 p2]).then((result) => {  console.log(result); //打印[1,2]
}).catch((error) => {
  console.log(error)
})

写的不是很全,今天身体不好,写的不详细,对不起,等挑战结束我再编辑一下

四、使用async、await

async关键字表示整个代码中有异步执行的方法,但是也可以没有;可以传很多参数没有限制;会默认返回promise对象的resolve值。

await只能在async定义的方法中使用,否则会报错,后面跟promise对象,如果不是的话,系统会自动转化为promise对象

//async使用:
async function fun1() {
    return "hello async";
}

const result = fun1(); // 返回一个Promise对象
//和promise一样,可以执行then方法
fun1().then(str=> {
    console.log(str);})

和await配合使用

async function fun1() {
    let res = await fun2(1);
    console.log(res);
}

function fun2(num){
    num++;
    return num;}

五、事件监听

事件类型有:click,on,bind,listen,addEventListener,observe等

事件监听取决于你什么时候触发,导致异步

<div id="handlerClick1">提交1</div>

function fun1() {
    setTimeout(()=> {
        fun2();
    })
}
$("#handlerClick1").click(function() {
    fun1();
})
function fun2() {
    console.log(23);
}

六、发布订阅者模式(观察者模式)

这个简单来说就是你在elm点了一个外卖(订阅subscriube),平台收到你的请求后开始执行配送,外卖小哥送达后完成订单(publish('done'))告诉平台已经结束这一单。

//以jq为例
jQuery.subscribe('done',fun1);

function fun1() {
    //详细执行商家做菜和配送的操作
    jQuery.publish('done');//配送完告诉elm完成订单
}

一共整理了6种不知道全不全,写了两个小时,感觉写的挺少的,当学习了~