摘要:到这里,我已经发出了一个请求买汉堡,启动了一次交易。但是做汉堡需要时间,我不能马上得到这个汉堡,收银员给我一个收据来代替汉堡。到这里,收据就是一个承诺保证我最后能得到汉堡。
同期异步系列文章推荐
谈一谈javascript异步
javascript异步中的回调
javascript异步之Promise.all()、Promise.race()、Promise.finally()
javascript异步之Promise.resolve()、Promise.reject()
javascript异步之Promise then和catch
javascript异步之async(一)
javascript异步之async(二)
javascript异步实战
javascript异步总结归档
我们说处理javascript异步最常用的方式就是通过回调函数,对于回调函数我们昨天对此做了介绍
简单快速,
我们一般使用嵌套回调或者链式回调,会产生以下问题
当采用嵌套回调时,会导致层级太多,不利于维护
所以我们又采用了链式回调,对嵌套回调进行拆分,拆分后的函数间耦合度很高,
如果需要传递参数,函数之间的关联性会更高,而且要对参数进行校验以提高代码的健壮性
如果将我们自己的回调函数传递给第三方插件或者库,就要考虑一些不可控因素
调用回调过早
调用回调过晚(或不被调用)
调用回调次数过多或者过少
promise的存在就是为了解决以上问题
虽然我们日常写回调函数不会有这么严格的要求,但是如果不这样去写回调函数,就会存在隐患,当在团队协作的时候,显得编码规范显得尤为重要
本文不重点介绍如何使用promise,重点介绍的是promise解决了哪些异步回调出现的问题。
什么是promise我们来看一个场景,有助于我们了解promise
设想一下这个场景,我去KFC,交给收银员10元,下单买一个汉堡,下单付款。到这里,我已经发出了一个请求(买汉堡),启动了一次交易。
但是做汉堡需要时间,我不能马上得到这个汉堡,收银员给我一个收据来代替汉堡。到这里,收据就是一个承诺(promise),保证我最后能得到汉堡。
所以我需要好好的保留的这个收据,对我来说,收据就是汉堡,虽然这张收据不能吃,我需要等待汉堡做好,等待收银员叫号通知我
等待的过程中,我可以做些别的事情
收银员终于叫到了我的号,我用收据换来了汉堡
当然还有一种情况,当我去柜台取汉堡的时候,收银员告诉我汉堡卖光了,做汉堡的师傅受伤了等等原因,导致了我无法得到这个汉堡
虽然我有收据(承诺),但是可能得到汉堡(成功),可能得不到汉堡(失败)
我由等待汉堡变成了等到或者等不到,这个过程不可逆,
上面很形象的介绍了promise,上面的等待汉堡和得到汉堡,汉堡卖光了,得不到汉堡,分别对应promise的三种状态
三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)(一旦状态改变,就不会再变)
调用过早就是将异步函数作为同步处理了,
我们之前说过,javascript以单线程同步的方式执行主线程,遇到异步会将异步函数放入到任务队列中,
当主线程执行完毕,会循环执行任务队列中的函数,也就是事件循环,直到任务队列为空。
事件循环就像是一个游乐场,玩过一个游戏后,你需要重新排到队尾才能再玩一次
任务队列就是,在你玩过一个游戏后,可以插队接着玩
我们看一个栗子
const promise = new Promise((resolve, reject) => { resolve("成功啦") }); promise.then(res => { console.log(res); console.log("我是异步执行的"); }) console.log("我在主线程");
看下输出,重点看输出顺序
//我在主线程 //成功啦 //我是异步执行的
直接手动是promise的状态切为成功状态,console.log("我是异步执行的");这段代码也是异步执行的
提供给then()的回调永远都是异步执行的,所以promise中不会出现回调函数过早执行的情况
回调函数调用过晚的处理原理和调用过早很类似,
在promise的then()中存放着异步函数,所有的异步都存在于js的任务队列中,当js的主线程执行完毕后,会依次执行任务队列中的内容,不会出现执行过晚的情况
我们用栗子说话
const promise = new Promise((resolve, reject) => resolve("成功啦")) promise.then(s => console.log(s)); console.log("我在主线程");
成功状态的输出
//我在主线程 //成功啦
成功状态下回调被调用
继续看一下失败的回调
const promise = new Promise((resolve, reject) => reject("失败啦")) promise.then(null, s => console.log(s)); console.log("我在主线程");
失败状态的输出
//我在主线程 //失败啦
失败状态下回调被调用
所以说,不管是失败还是成功,回调函数都会被调用
我们之前说了promise有三种状态
pending(进行中)、fulfilled(已成功)和rejected(已失败)状态一旦状态改变,就不会再变
一个栗子
const promise = new Promise((resolve, reject) => { reject("失败啦") resolve("成功啦") }); promise.then(res => { console.log(`我是异步执行的成功:${res}`); },err=>{ console.log(`我是异步执行的失败:${err}`); }).catch(err => { console.log(err); }) console.log("我在主线程");
输出
//我在主线程 //我是异步执行的失败:失败啦
当状态变为失败时,就不会再变为成功,成功的函数也不会执行,反之亦然
调用次数过少回调函数正常是调用一次,过少=>0次=>回调函数不被调用,上面刚刚讨论过
原文链接
参考链接
JavaScript Promise 迷你书
Promise 对象
ES6 系列之我们来聊聊 Promise
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/101268.html
摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。写一个符合规范并可配合使用的写一个符合规范并可配合使用的理解的工作原理采用回调函数来处理异步编程。 JavaScript怎么使用循环代替(异步)递归 问题描述 在开发过程中,遇到一个需求:在系统初始化时通过http获取一个第三方服务器端的列表,第三方服务器提供了一个接口,可通过...
摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...
摘要:为这些回调函数分别命名并分离存放可以在形式上减少嵌套,使代码清晰,但仍然不能解决问题。如果在一个结束成功或失败,同前面的说明后,添加针对成功或失败的回调,则回调函数会立即执行。 异步? 我在很多地方都看到过异步(Asynchronous)这个词,但在我还不是很理解这个概念的时候,却发现自己常常会被当做已经很清楚(* ̄ロ ̄)。 如果你也有类似的情况,没关系,搜索一下这个词,就可以得到大致...
摘要:的执行与状态无关当得到状态不论成功或失败后就会执行,原文链接参考链接对象 同期异步系列文章推荐谈一谈javascript异步javascript异步中的回调javascript异步与promisejavascript异步之Promise.resolve()、Promise.reject()javascript异步之Promise then和catchjavascript异步之async...
摘要:最受欢迎的引擎是,在和中使用,用于,以及所使用的。怎么处理每个引擎都有一个基本组件,称为调用栈。也就是说,如果有其他函数等待执行,函数是不能离开调用栈的。每个异步函数在被送入调用栈之前必须通过回调队列。例如方法是在中传递的回调函数。 翻译:疯狂的技术宅 原文:www.valentinog.com/blog/engine… 从Call Stack,Global Me...
阅读 2906·2020-01-08 12:17
阅读 1957·2019-08-30 15:54
阅读 1121·2019-08-30 15:52
阅读 1996·2019-08-29 17:18
阅读 1008·2019-08-29 15:34
阅读 2422·2019-08-27 10:58
阅读 1837·2019-08-26 12:24
阅读 341·2019-08-23 18:23