和catch的区别_异步和同步的区别?

本文深入探讨了JavaScript中的异步编程原理,重点讲解了任务队列和同步、异步任务的区别。通过实例展示了如何使用Async/Await简化异步代码,对比了与Promise的区别,强调了Async/Await在错误处理、条件语句和中间值处理上的优势,以及在调试方面的便利。此外,还解释了try...catch在异步代码中的作用。
摘要由CSDN通过智能技术生成

各位老铁,元旦快乐,好久不见,新的一年愿你们事业有成,平安幸福。最近在做项目的时候遇到了异步的知识和用法,自己对这方面不清楚,所以找资料来了解一下。

一、原理如下:

同步和异步的差别就在于这条流水线上各个流程的执行顺序不同同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。

这里说到了一个“队列”(即任务队列),该队列放的是什么呢,放的就是setTimeout中的function,这些function依次加入该队列,即该队列中所有function中的程序将会在该队列以外的所有代码执行完毕之后再以此执行,这是为什么呢?因为在执行程序的时候,浏览器会默认setTimeout以及ajax请求这一类的方法都是耗时程序(尽管可能不耗时),将其加入一个队列中,该队列是一个存储耗时程序的队列,在所有不耗时程序执行过后,再来依次执行该队列中的程序。

又回到了最初的起点——javascript是单线程。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念——任务队列。如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。于是JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。

具体来说,异步运行机制如下:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

二、那么就拿实际代码来举例,在项目开发中常常会遇到异步请求接口的问题

 (1.)什么是Async/Await?

      async/await是写异步代码的新方式,以前的方法有回调函数和Promise。

  async/await是基于Promise实现的,它不能用于普通的回调函数。
  async/await与Promise一样,是非阻塞的。
  async/await使得异步代码看起来像同步代码,这正是它的魔力所在。

 Async/Await语法

 假设函数getJSON返回值是 Promise,并且 Promise resolves 有一些JSON 对象。我们只想调用它并且记录该JSON并且返回完成。

  1)使用Promise:

    const makeRequest = () =>
getJSON().then(data => {
console.log(data)
return "done"
})
makeRequest()

2)使用Async:

    const makeRequest = async () => {
// await getJSON()表示console.log会等到getJSON的promise成功reosolve之后再执行。
console.log(await getJSON)
return "done"
}
makeRequest()

 区别:

  1)函数前面多了一个aync关键字。await关键字只能用在aync定义的函数内。async函数会隐式地返回一个promise,该promise的reosolve值就是函数return的值。(示例中reosolve值就是字符串”done”)
  2)第1点暗示我们不能在最外层代码中使用await,因为不在async函数内。例如:

    // 不能在最外层代码中使用await
await makeRequest()
// 这是会出事情的
makeRequest().then((result) => {
// 代码
})

 为什么Async/Await更好?

  1)使用async函数可以让代码简洁很多,不需要像Promise一样需要写then,不需要写匿名函数处理Promise的resolve值,也不需要定义多余的data变量,还避免了嵌套代码。

  2) 错误处理:
    Async/Await 让 try/catch 可以同时处理同步和异步错误。在下面的promise示例中,try/catch 不能处理 JSON.parse 的错误,因为它在Promise中。我们需要使用 .catch,这样错误处理代码非常冗余。并且,在我们的实际生产代码会更加复杂。

    const makeRequest = () => {
try {
getJSON().then(result => {
// JSON.parse可能会出错
const data = JSON.parse(result)
console.log(data)
})
// 取消注释,处理异步代码的错误
// .catch((err) => {
// console.log(err)
// })
} catch (err) {
console.log(err)
}
}

   使用aync/await的话,catch能处理JSON.parse错误:

    const makeRequest = async () => {
try {
// this parse may fail
const data = JSON.parse(await getJSON())
console.log(data)
} catch (err) {
console.log(err)
}
}

 3)条件语句
    条件语句也和错误捕获是一样的,在 Async 中也可以像平时一般使用条件语句

    Promise:

    const makeRequest = () => {
return getJSON().then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data).then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}

    Async/Await:

    const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}

 4)中间值
    你很可能遇到过这样的场景,调用promise1,使用promise1返回的结果去调用promise2,然后使用两者的结果去调用promise3。

    const makeRequest = () => {
return promise1().then(value1 => {
return promise2(value1).then(value2 => {
return promise3(value1, value2)
})
})
}

    如果 promise3 不需要 value1,嵌套将会变得简单。如果你忍受不了嵌套,你可以将value 1 & 2 放进Promise.all来避免深层嵌套,但是这种方法为了可读性牺牲了语义。除了避免嵌套,并没有其他理由将value1和value2放在一个数组中。

    const makeRequest = () => {
return promise1().then(value1 => {
return Promise.all([value1, promise2(value1)])
}).then(([value1, value2]) => {
return promise3(value1, value2)
})
}

    使用async/await的话,代码会变得异常简单和直观。

    const makeRequest = async () => {
const value1 = await promise1()
const value2 = await promise2(value1)
return promise3(value1, value2)
}

6)调试
     async/await能够使得代码调试更简单。2个理由使得调试Promise变得非常痛苦:

   《1》不能在返回表达式的箭头函数中设置断点
   《2》如果你在.then代码块中设置断点,使用Step Over快捷键,调试器不会跳到下一个.then,因为它只会跳过异步代码。

   使用await/async时,你不再需要那么多箭头函数,这样你就可以像调试同步代码一样跳过await语句。

代码示例

c31c50aa86ec0599630b84a53e6cd054.png

ac1d85fa40d5d5a53fd0a6bebff264eb.png

029c29a05cbe65687dff9bc4729fdf26.png

先去执行await里面的,按js代码从上到下顺序执行,等都拿到值后,才会打印出最后的值,往往用在调用接口时,有先后顺序的情况下

try ...catch ... 的作用

try  是测试代码块,抛出异常,catch 是捕获异常,好处是不会影响程序运行

3f0c7c6881921551d1ef8f5f78896eab.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值