对于异步的一些理解

本文深入探讨了JavaScript的单线程特性及其对DOM渲染的影响,解释了异步编程的必要性和实现方式,包括事件轮询机制,以及通过Promise、Async/Await和JQuery的Defferred来解决异步问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是单线程,和异步有什么关系

单线程:同一时间,只能做一件事;
js中单线程的原因:避免DOM渲染的冲突。
js执行和DOM渲染是共用一个线程的:两段js不能同时执行,js执行的时候DOM渲染会暂停;
单线程的解决方案–异步。
在js的世界中,所有的代码都是单线程执行的,由于这个“缺陷”,导致js所有网络操作,浏览器事件都必须是异步执行。
异步函数:setTimeout /ajax/setinterval/promise

2、异步的实现方式: 事件轮询(event-loop)

同步代码直接执行,同步函数放在主进程中,会立即执行,异步函数放在异步队列中。同步代码(主进程中的代码)执行完后js引擎会不断监视异步队列中是否有函数,若有会立即把异步队列中的函数放到主进程中执行,执行完后,js引擎再次到异步队列中查找异步函数并放到主进程执行,如此循环,称作事件轮询。
setTimeout(function(){ //100ms后会将此函数放在异步队列中
console.log(1);
},100)

3、解决异步的方案

1)promise:promise的基本使用和原理
三种状态:pending fulfiled rejected,处理状态是:pending.状态变化:pending->fulfiled或者pending->rejected;
promise最大的好处是在异步的执行流程中,吧执行代码和处理结果的代码清晰地分离开,下面写个Pomise例子:
function loadImg(src){
  const promise = new Promise(function(resovle,reject){
    var img = document.createElement('img');
    img.onload = function(){
     resolve(img);
    }
    img.onerror = function() {
     reject();
    }
    img.src = src;
  })
  return promise ;
}
var result = loadImg(src);
result.then(function(img){
   console.log(img.width);
},function(){
  console.log('failed');
}).then((function(img){
   console.log(img.height);
})

var r1 = loadimg(src);
var r2 = loadiimg(src);
r1.then(function(img){
console.log(‘第一张图片加载完成’);
rturn r1;
}).then(function(img){
console.log(‘第二张图片加载完成’);
})
all和race
promise的详细介绍:廖雪峰的官网

promise原理
其实,promise就是三个状态。利用观察者模式,只需要通过特定书写方式注册对应状态的事件处理函数,然后更新状态,调用注册过的处理函数即可。
这个特定方式就是then,done,fail,always…等方法,更新状态就是resolve、reject方法。 摘自promise原理浅析

 2)  Async Awiat(es7)
 async 函数返回的是一个promise 对象;关键字await 表示等一下,代码就暂停到这里,不再向下执行了,它等什么呢?等后面的promise对象执行完毕,然后拿到promise resolve 的值并进行返回,返回值拿到之后,它继续向下执行。特点:完全是同步的写法,再也没有回调函数。
 写个例子:
 function yibuFn (num){
    //返回promise 对象
    return new Promise(function(resolve,reject){
      setTimeout(function(){
        if(num>30){
          resolve(num*2);
        }else{
           reject(num+1);
        }
      },1000)
    })
 }
 async function test(){
   let result1 = await yibuFn(50); 
   console.log("result1:",result1);
   let result2 = await yibuFn(20); 
   console.log("result2:",result2 );
 }
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181202233540919.png)
 [详细介绍见博客](https://www.cnblogs.com/SamWeb/p/8417940.html)
 
 3)JQuery的Defferred(JQuery1.5以后)
 
 function waitHandle(){
   var dtd = $.Deferred();
   var wait = function (dtd){
      var task = function(){
        console.log("执行完成");
        dtd.resolve();//成功
        // dtd.reject();//失败
      }
      setTimeout(task,1000);
      return dtd.promise(); //wait返回
   }   
   return wait(dtd);
 }

var w = waitHandle(); //promise对象
$.when(w).then(function(){
console.log(‘ok1’);
},function(){
console.log(‘error 1’);
});
在写法上杜绝了callback这种形式
一种语法糖,但是解耦了代码
很好的体现:开放封闭原则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值