promise和async

由于javascript是单线程的,只能在JS引擎的主线程上运行的,所以js代码只能一行一行的执行,不能在同一时间执行多个js代码任务,这就导致如果有一段耗时较长的计算,或者是一个ajax请求等IO操作,如果没有异步的存在,就会出现用户长时间等待,并且由于当前任务还未完成,所以这时候所有的其他操作都会无响应。

那么常见的异步模式有哪些呢?

回调函数

事件监听

发布/订阅模式(又称观察者模式)

promise

具体JS是如何实现异步操作的呢?

当JS解析执行时,会被引擎分为两类任务,同步任务(synchronous) 和 异步任务(asynchronous)。

对于同步任务来说,会被推到执行栈按顺序去执行这些任务。对于异步任务来说,当其可以被执行时,会被放到一个 任务队列(task queue) 里等待JS引擎去执行。

当执行栈中的所有同步任务完成后,JS引擎才会去任务队列里查看是否有任务存在,并将任务放到执行栈中去执行,执行完了又会去任务队列里查看是否有已经可以执行的任务。这种循环检查的机制,就叫做事件循环(Event Loop)。

1.回调函数:当一个函数作为参数传入另一个参数中,并且它不会立即执行,只有当满足一定条件后该函数才可以执行,这种函数就称为回调函数。我们熟悉的定时器和Ajax中就存在有回调函数:

2.回调地狱:存在异步执行的代码,不能按顺序执行,所以代码回调函数嵌套回调函数,形成回调地狱

3.promise

主要用于异步计算:作用:为了避免界面冻结

Promise是js中的一个原生对象,是一种异步编程的解决方案,可以替换掉传统的回调函数解决方案。

promise构造函数接收一个函数作为参数,需要异步任务就卸载该函数体,该函数的两个参数是resolve,reject,异步任务执行成功时调用resolve,错误调用reject

promise对象的then方法用来接收处理成功时响应的数据,catch方法用来接收处理失败的函数

promise的链式编程可以保证代码的执行顺序,前提是每一次在then做完处理后一定要return一个promise对象,这样才能在下一次then时接收到数据

假如在.then()的函数里面不返回新的promise,会怎样?

.then()

1、接收两个函数作为参数,分别代表fulfilled(成功)和rejected(失败) 2、.then()返回一个新的Promise实例,所以它可以链式调用 3、当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行 4、状态响应函数可以返回新的promise,或其他值,不返回值也可以我们可以认为它返回了一个null; 5、如果返回新的promise,那么下一级.then()会在新的promise状态改变之后执行 6、如果返回其他任何值,则会立即执行下一级.then()

promise有三个状态:1、pending[待定]初始状态2、fulfilled[实现]操作成功3、rejected[被否决]操作失败

Promise会自动捕获内部异常,并交给rejected响应函数处理。

错误处理两种做法: 第一种:reject('错误信息').then(() => {}, () => {错误处理逻辑}) 第二种:throw new Error('错误信息').catch( () => {错误处理逻辑}) 推荐使用第二种方式,更加清晰好读,并且可以捕获前面所有的错误(可以捕获N个then回调错误)

async和await

异步函数是使用async关键字声明的函数,其中允许使用await关键字。async和await关键字使基于承诺的异步行为能够以更简洁的风格编写,从而避免了显式配置承诺链的需要。

async

作为一个关键字放在函数的前面,表示该函数是一个异步函数,意味着该函数的执行不会阻塞后面代码的执行 异步函数的调用跟普通函数一样

await

await即等待,用于等待一个promise对象。只能在异步函数async function使用,他的返回值不是promise对象而是promise对象处理的结果,await表达式会暂停当前async function的执行,等待promise处理完成。若promise正常处理(fulfilled),其回调的resolve函数参数作为await的表达式的值,继续执行async function,若promise处理异常(rejected),await表达式会把promise的异常原因抛出,如果 await 操作符后的表达式的值不是一个 Promise,那么该值将被转换为一个已正常处理的 Promise

与Promise对比1、不再需要多层.then方法假设一个业务分很多步骤完成,并且每个步骤都是异步,依赖上一个步骤的结果。

2、可以对Promise进行并行处理

function takeLongTime(n) {
   return new Promise(resolve => {
       setTimeout(() => resolve(n + 200), n);
   });
}
function step1(n) {
   console.log(`step1 with ${n}`);
   return takeLongTime(n);
}
function step2(n) {
   console.log(`step2 with ${n}`);
   return takeLongTime(n);
}
function step3(n) {
   console.log(`step3 with ${n}`);
   return takeLongTime(n);
}

Promise方式

function doIt() {
   console.time("doIt");
   const time1 = 300;
   step1(time1)
       .then(time2 => step2(time2))
       .then(time3 => step3(time3))
       .then(result => {
           console.log(`result is ${result}`);
           console.timeEnd("doIt");
       });
}
doIt();

// async await方式

async function doIt() {
   console.time("doIt");
   const time1 = 300;
   const time2 = await step1(time1);
   const time3 = await step2(time2);
   const result = await step3(time3);
   console.log(`result is ${result}`);
   console.timeEnd("doIt");
}
doIt();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容