11. Promise与异步编程

1. 异步编程:

js是单线程事件循环。单线程就是:函数逐步运行的时候,要从上至下顺序执行。js引擎同一时刻只能执行一个代码块。这些代码块被准备执行都会加入任务队列。每段代码执行完毕,进入下一个代码块。

1.1. 事件模型:

当点击触发onClick等事件,会向任务队列增加一个新任务【代码块】相应操作。最基础的异步编程模式。

1.2. 回调模式:

与事件模型类似,函数会在未来某个时间点完成。区别是,回调模式的函数当做参数进行传入。(NodeJS错误优先原则)

缺点:
1. 但是如果回调函数嵌套过多,会先入回调地狱。
2. 如果想让两个异步操作,取得优先执`行完成的异步,这些操作将会难以完成。

2. Promise

概念:Promise是为异步操作的结果所准备的占位符。

2.1.Promise生命周期
  1. 挂起态(异步操作尚未结束)——>已决的(已经完成)1. 成功完成 2. 失败完成
  2. 我们不能直接获取promise对象的状态值,但是我们可以通过.then函数在Promise状态改变时执行 一些特定操作。
    .then(函数1, 函数2)第一个参数是成功时执行的函数,第二个参数是失败时执行的函数
    .catch(函数1)只传入执行失败的函数

.then()都是thenable函数。所有的Promise都是 thenable,但是不是所有的thenable都是promise

  1. promise的完成程序被调用,再在里面添加另一个完成处理程序,这个新的完成处理程序会被添加到任务队列中。
2.3.创建未完成的promise
new Promise(包含处理华promise的代码执行器(resolve函数, reject函数) {处理成功, resolve(结果), 执行不成功, reject(结果)})

执行器会立即执行!!!
对于任务编排没有了解过。
new Promise会立即执行,并且【猜测】是阻塞执行的。之后的.then是在promise函数完成之后才会调用。

2.4.创建已完成的promise

目的:想用Promise表示一个已知值,只是简单给resolve()函数传值。

  1. 创建已完成的成功promise
let pro = Promise.resolve(42);
pro.then(res => {console.log(res)});

当然,是我我肯定这样写

let pro = new Promise(function () { resolve(45)});
pro.then(res => {console.log(res)});

上一中方法写的好处永远不会存在拒绝状态

  1. 创建已完成的成功promise
let pro = Promise.reject(42);
pro.catch(res => {console.log(res)});

!!!如果向Pomise.resolve()方法或者 Promise.reject()方法传入一个Promise函数,那么这个Promsie函数会被直接返回。【理解,哪怕直接返回了,返回出来不也会立即执行吗,因为有执行器,而执行器会立即执行】

3.非Promise的Thenable函数
含义:拥有.then并且接受(resolve, reject)这两个参数作为普通对象
Promise.reject()和Promise.resolve()都可以接受非promise的thenable函数作为参数。并且这些方法会创建一个新的promise,并在.then函数中调用。

let thenAble = {
  then : function(resolve,  reject) {
    resolve(43);
  }
}
let testPro = Promise.resolve(thenAble);
testPro.then(res => {console.log(res)}); // 43
console.log('333333');
let testPro = Promise.resolve(
  new Promise(function (resolve) {
      console.log('1111111'); 
      resolve('11111111')}
   )
).then(res => 
  console.log('2222222'+res)
);
console.log('444444444')
// 33333    11111        44444   22222111111 resolve会阻断   then不是阻断的
2.4.执行器错误

如果执行器内部抛出错误threw new Error('error')。Promise对象的.catch()方法会被调用。只有当拒绝处理程序存在时,才会在记录执行器抛出的错误,否则错误会被忽略掉。
【记录:在哪儿记录?console里面报错吗? 拒绝处理程序: reject函数么?】

3.全局的promise拒绝处理

promise.reject()不会进行报错,因为不知道他在什么时候进行这个报错处理。因此,没法进行强制报错。

3.1.NodeJS环境的拒绝处理

【看不明白,不知道事件循环,不了解nodeJS】
NodeJs中。处理promise拒绝时会触发process对象上的两个时间。
unhandledRejection 在事件循环【???】中,Promise被决绝,没有提供处理函数会触发事件。
rejectionHandled 若一个 Promise 被拒绝、并在事件循环的一个轮次之后再有拒绝处理函数被调用,该事件就会被触发。

将1. 拒绝原因 2. 被拒绝的promise作为参数被传入unhandledRejection

let rejected;
process.on("unhandledRejection", function(reason, promise) {                 
    console.log(reason.message); // "Explosion!"
    console.log(rejected === promise);  //  true 
});
rejected = Promise.reject(new Error("Explosion!"));

3.2.浏览器的拒绝处理

4.串联的promise

每次调用.then()或者.catch()都返回了另一个Promise只有第一个完成才会进行第二个。

let p1 = new Promise(function(res, rej) {
  res(42)
})
let p2 = p1.then(res => {
  console.log(res);
})
p2.then(res => {
  console.log(res);
})

思考: 既然是p2是promise 那样在哪儿resolve();的呢??让他可以.then。为什么不p2 resolve之后才能调用p2.then????

4.1.捕获错误

和上面相同原理。但是注意,不能一直向外抛出错误,总得解决掉他。

4.2.promise链的返回值

在.then中使用return语句,可以在下一个.then中拿到上一个return的值

4.3.promise链中返回promise

作用:给下游的promise返回值

p1.then(return 值).then(值 => {})
p2.catch(return 值).then(值 => {})
4.4.promise链中返回promise

体会:

let p1 = new Promise(function(resolve, reject){ console.log('111111111'); resolve(1) });
let p2 = new Promise(function(resolve, reject){ console.log('222222222'); resolve(2) });
let p3 = new Promise(function(resolve, reject){ console.log('333333333'); reject(3) });
let p4 = p1.then(res => {console.log(res); return p2});
let p5 = p4.then(res => {console.log(res); return p3});
let p6 = p5.catch(res => {console.log(res)});

p1.then()生成promise函数。之后p5.then()就是调用这个promise中的.then。至于为什么不是p2的promise,规定吧。当p3抛出错误,p5作为p3的包装的promise,当然应该能拿到。我是这样理解的。

5.响应多个Promise

Promise.all() / Promise.race()

5.1.Promise.all()

接收一个参数并返回Promise,该参数是含有多个受监视Promise的可迭代对象。只有当所有完成之后,才会执行all方法。当有一个拒绝,立马调用catch函数

let p1 = new Promise(function(resolve, reject){ console.log('111111111'); resolve(1) });
let p2 = new Promise(function(resolve, reject){ console.log('222222222'); resolve(2) });
let p3 = new Promise(function(resolve, reject){ console.log('333333333'); resolve(3) });
let p4 = Promise.all([p1, p2, p3]);
p4.then(val => {console.log(val)});
//111111111  222222222 333333333 (3) [1, 2, 3]

let p1 = new Promise(function(resolve, reject){ console.log('111111111'); resolve(1) });
let p2 = new Promise(function(resolve, reject){ console.log('222222222'); resolve(2) });
let p3 = new Promise(function(resolve, reject){ console.log('333333333'); reject(3) });
let p4 = Promise.all([p1, p2, p3]);
p4.then(val => {console.log(val)});
p4.catch(val => {console.log(val)});
// 111111111  222222222  333333333  3
5.2.Promise.race()

当有一个Promise被resolve就会被调用。传参方式相同。传入的res是第一个resolve的值。当一个执行完成的Promise的函数是被拒绝状态,

let p1 = new Promise(function(resolve, reject){ console.log('111111111'); setTimeout(() => {resolve(20)}, 1000) });
let p2 = new Promise(function(resolve, reject){ console.log('333333333'); reject(3) });
let p4 = Promise.race([p1, p2]);
p4.then(val => {console.log(val)}); // 这里没执行??
p4.catch(val => {console.log(val)});
//111111111 333333333 3

6.自Promse继承

// 类的继承吧

7.基于Promise的异步任务执行

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

推荐阅读更多精彩内容