异步、同步以及异步的各种解决方法 最全解!

1. 异步和同步

JavaScript是单线程语言,所谓"单线程",就是指一次只能完成一件任务。遇到等待(网络请求、定时任务)会卡住,所以需要异步模式。

同步和异步的区别:
同步模式:后一个任务等待前一个任务结束,然后再执行,如果遇到等待会阻塞代码的执行;
异步模式: 后一个任务不等待前一个任务结束就可以执行,不会阻塞代码的执行。异步通过callback形式调用。

具体来说,异步运行机制如下:
(1)所有同步任务都在主线程上排队依次执行,形成一个执行栈。
(2)主线程之外,还存在一个"任务队列"(task queue)。异步任务进入Event Table并注册函数,异步任务有了运行结果,就在“任务队列”之中放置一个事件。
(3)一旦主线程中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入主线程执行。
(4)主线程内的任务执行完毕为空,就会从"任务队列"中读取事件,这个过程是循环不断的,形成event loop(事件循环)

//异步    通过callback形式调用    异步不会阻塞代码执行
console.log(100)
setTimeout(() => {
    alert(200)
},1000)
console.log(400)  //100,400 ,200

//同步   必须点击确认,400才能打印出来,同步会阻塞代码执行
console.log(100)
alert(200)
console.log(400)

异步方案经历了如下的四个进化阶段:
回调函数 —> Promise —> Generator —> async/await。

2.回调函数时期

异步的实现方式:事件监听,发布订阅,回调函数
异步可以同时进行多个操作,不会阻塞代码的执行,但同时他也有缺点,它使代码变得很复杂,比如一个页面进行多个ajax请求时:

$.get(url1,(data1) => {
   console.log(data1)
   //获取第二份数据
   $.get(url2, (data2) => {
       console.log(data2)
       //获取第三份数据
       $.get(url3, (data3) => {
           console.log(data3)
			//还可以继续获取数据
       })
   })
})

这样的代码会变得难以调试,并且极易出错,这就是callback hell(回调地狱)。
ES6的新语法Promise对象解决了callback hell问题。

3. Promise

Promise 对象用于表示一个异步操作的最终结果(完成或失败),以及其返回的值。

const https = require('https');

function httpPromise(url){
  return new Promise(function(resolve,reject){
    https.get(url, (res) => {
      resolve(data);
    }).on("error", (err) => {
      reject(error);
    });
  })
}
httpPromise()
.then(function(data){
	console.log(data)
})
.catch(function(error){
	console.log(error)
})
//在上面这个例子里,当我们用 resolve 切换到了成功态后,Promise 的逻辑就会走到 then 中的传入的方法里去;
// 用 reject 切换到失败态后,Promise 的逻辑就会走到 catch 传入的方法中去。
httpPromise(url1)
    .then(res => {
        console.log(res);
        return httpPromise(url2);
    })
    .then(res => {
        console.log(res);
        return httpPromise(url3);
    })
    .then(res => console.log(res));

4. Generator

5. Async await

async/await的出现是将异步函数变成同步写法,使复杂的代码更可读。
async关键字声明一个函数为异步函数:

async function httpRequest() {
  }

await关键字将异步方法变成同步方法,阻塞了代码的执行,它是等待异步方法执行完成,然后获取异步方法里的数据,但是必须用在异步方法里。

async function httpRequest() {
  let res1 = await httpPromise(url1)
  console.log(res1)
} 
//我们给 httpPromise(url1) 这个异步任务应用了 await 关键字后,整个函数会暂停下来,直到异步任务的结果返回后,它才会被“唤醒”,继续执行后面的语句。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值