ES6-Promise下
六。实例的finally方法:
promise状态发生变化指的是由初始态变成成功或者失败态
处理错误指的是没有调用catch(失败态实例调用可以执行其回调的then)
finally里面的回调函数只要promise状态发生变化就会执行,但是接收不到参数
这里没有调用then方法,也会报错吗?什么时候报错?
应用场景:处理最终状态,比如js操作数据库,涉及异步操作,可以用promise,最终需要关闭数据库不论成功或者失败
finally的本质:
new Promise(function (resolve, reject) {
// resolve(1);
reject('reason');
}).finally(function () {
console.log(1);
});
// 相当于下面
new Promise(function (resolve, reject) {
// resolve(1);
reject('reason');
})
.then(
result => {
console.log(1);
return result;
},
err => {
console.log(1);
return new Promise(function (resolve, reject) {
reject(err);
});
}
);
finally源码
// 1.什么时候finally里面的回调执行
// 当 Promise 状态发生变化时,不论如何变化都会执行,不变化不执行
// new Promise((resolve, reject) => {
// // resolve(123);
// reject('reason');
// })
// .finally(data => {
// console.log(data);
// })
// .catch(err => {});
// 2.本质
// finally() 本质上是 then() 的特例
// new Promise((resolve, reject) => {
// // resolve(123);
// reject('reason');
// })
// .finally(data => {
// console.log(data);
// })
// .catch(err => {});
// 等同于
new Promise((resolve, reject) => {
// resolve(123);
reject('reason');
})
.then(
result => {
return result;
},
err => {
return new Promise((resolve, reject) => {
reject(err);
});
}
)
.then(data => {
console.log(data);
})
.catch(err => {
console.log(err);
});
七。构造函数Promise的方法
1.Promise.resolve()和Promise.reject()
注意,也不一定Promise.resolve()返回的就是成功状态p,看下面传有then方法的一般对象;
所以data接收的参数是p1实例里resolve的参数,也就是由p1接手了;
疑问:(前面已经解答)
解释为什么有这两个函数
同步异步定时器问题,去掉return问题前面的,为什么有的等1秒,有的不等
注意,挂起的then里面的回调会等当前的正在主车道执行的代码执行完再执行;
源码
<script>
// 1.Promise.resolve()
// 是成功状态 Promise 的一种简写形式
// new Promise(resolve => resolve('foo'));
// // 简写
// Promise.resolve('foo');
// 参数
// 一般参数
// Promise.resolve('foo').then(data => {
// console.log(data);
// });
// Promise
// 当 Promise.resolve() 接收的是 Promise 对象时,直接返回这个 Promise 对象,什么都不做
// const p1 = new Promise(resolve => {
// setTimeout(resolve, 1000, '我执行了');
// // setTimeout(() => {
// // resolve('我执行了');
// // }, 1000);
// });
// Promise.resolve(p1).then(data => {
// console.log(data);
// });
// 等价于
// p1.then(data => {
// console.log(data);
// });
// console.log(Promise.resolve(p1) === p1);
// 当 resolve 函数接收的是 Promise 对象时,后面的 then 会根据传递的 Promise 对象的状态变化决定执行哪一个回调
// new Promise(resolve => resolve(p1)).then(data => {
// console.log(data);
// });
// 具有 then 方法的对象
// function func(obj) {
// obj.then(1, 2);
// }
// func({
// then(resolve, reject) {
// console.log(a, b);
// }
// });
// const thenable = {
// then(resolve, reject) {
// console.log('then');
// resolve('data');
// // reject('reason');
// }
// };
// Promise.resolve(thenable).then(
// data => console.log(data),
// err => console.log(err)
// );
// console.log(Promise.resolve(thenable));
// 2.Promise.reject()
// 失败状态 Promise 的一种简写形式
// new Promise((resolve, reject) => {
// reject('reason');
// });
// 等价于
// Promise.reject('reason');
// 参数
// 不管什么参数,都会原封不动地向后传递,作为后续方法的参数
// const p1 = new Promise(resolve => {
// setTimeout(resolve, 1000, '我执行了');
// });
// Promise.reject(p1).catch(err => console.log(err));
new Promise((resolve, rejcet) => {
resolve(123);
})
.then(data => {
// return data;
// return Promise.resolve(data);
return Promise.reject('reason');
})
.then(data => {
console.log(data);
})
.catch(err => console.log(err));
</script>
2.Promise.all()方法
注意,参数里面有rejected实例的情况,只要根据代码执行顺序识别到有一个rejected实例,那么下图的p就变成失败态且接收识别到的失败态reject里面的参数a
等价于const p = Promise.reject(a),p和识别的那个rejected实例不是一个实例,只是参数和状态一样;
还有p由p1p2决定,p1p2赋值还未完成,所以p的赋值也未完成,同步执行时,定时器还没执行,delay函数return出去的也是暂时的,所以pp1p2也是暂时的pending状态,异步执行完毕,return后面的值刷新,delay(1000)delay(2000)的返回值也刷新,pp1p2的赋值也刷新;
如果all里面参数若为空数组的话,默认返回实例状态为成功
<script>
// 1.有什么用
// Promise.all() 关注多个 Promise 对象的状态变化
// 传入多个 Promise 实例,包装成一个新的 Promise 实例返回
// 2.基本用法
const delay = ms => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
};
const p1 = delay(1000).then(() => {
console.log('p1 完成了');
// return 'p1';
return Promise.reject('reason');
});
const p2 = delay(2000).then(() => {
console.log('p2 完成了');
return 'p2';
// return Promise.reject('reason');
});
// Promise.all() 的状态变化与所有传入的 Promise 实例对象状态有关
// 所有状态都变成 resolved,最终的状态才会变成 resolved
// 只要有一个变成 rejected,最终的状态就变成 rejected
const p = Promise.all([p1, p2]);
p.then(
data => {
console.log(data);
},
err => {
console.log(err);
}
);
</script>
<script>
const delay = ms => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
};
const p1 = delay(1000).then(() => {
console.log('p1 完成了');
return 'p1';
// return Promise.reject('reason');
});
const p2 = delay(2000).then(() => {
console.log('p2 完成了');
// return 'p2';
return Promise.reject('reason');
});
// 1.Promise.race()
// Promise.race() 的状态取决于第一个完成的 Promise 实例对象,如果第一个完成的成功了,那最终的就成功;如果第一个完成的失败了,那最终的就失败
// const racePromise = Promise.race([p1, p2]);
// racePromise.then(
// data => {
// console.log(data);
// },
// err => {
// console.log(err);
// }
// );
// 2.Promise.allSettled()
// Promise.allSettled() 的状态与传入的Promise 状态无关
// 永远都是成功的
// 它只会忠实的记录下各个 Promise 的表现
const allSettledPromise = Promise.allSettled([p1, p2]);
allSettledPromise.then(data => {
console.log('succ', data);
});
</script>
<script>
// 1.resolve 或 reject 函数执行后的代码
// 推荐在调用 resolve 或 reject 函数的时候加上 return,不再执行它们后面的代码
// new Promise((resolve, reject) => {
// // return resolve(123);
// return reject('reason');
// console.log('hi');
// });
// 2.Promise.all/race/allSettled 的参数问题
// 参数如果不是 Promise 数组,会将不是 Promise 的数组元素转变成 Promise 对象
// Promise.all([1, 2, 3]).then(datas => {
// console.log(datas);
// });
// 等价于
// Promise.all([
// Promise.resolve(1),
// Promise.resolve(2),
// Promise.resolve(3)
// ]).then(datas => {
// console.log(datas);
// });
// 不只是数组,任何可遍历的都可以作为参数
// 数组、字符串、Set、Map、NodeList、arguments
// Promise.all(new Set([1, 2, 3])).then(datas => {
// console.log(datas);
// });
// 3.Promise.all/race/allSettled 的错误处理
const delay = ms => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
};
const p1 = delay(1000).then(() => {
console.log('p1 完成了');
// return 'p1';
return Promise.reject('reason');
});
// .catch(err => {
// console.log('p1', err);
// });
const p2 = delay(2000).then(() => {
console.log('p2 完成了');
return 'p2';
// return Promise.reject('reason');
});
// // .catch(err => {
// // console.log('p2', err);
// });
const allPromise = Promise.all([p1, p2]);
allPromise
.then(datas => {
console.log(datas);
})
.catch(err => console.log(err));
// 错误既可以单独处理,也可以统一处理
// 一旦被处理,就不会在其他地方再处理一遍
</script>
九。promise应用
异步加载图片,停留在当前图片时,趁这个时间浏览器从服务器端加载其他资源,图片,然后点击切换按钮想要切换图片时,就可以显示到页面(通过dom),并不是点击切换才去服务器端加载这个图片
promise里的回调一般不写逻辑,一般写的是什么时候调用resolve或者reject;
如果不用promise的话,就会加两个形参接收回调函数,一个负责图片加载成功该怎么办,一个负责图片加载失败
注意img这里是个对象,是Image构造出来的实例,和dom对象没关系
注意这里的SRC属性是实例img的属性和html dom元素的SRC属性不一样
const img = new Image()只是实例化创建了一个img标签,也可以通过appendchild加入到html结构里
注意img.src=url,src属性值变化就能触发onload和onerror事件,img.src=url这个代码的作用就是一个工具,作用是像服务端发请求拿资源,这就是异步加载图片;
如果传进来的url并没有请求到图片,就会触发error事件
实际开发过程中,可能是点击按钮才切换图片;
如果图片加载失败(url错误)会有这个提示:
<style>
#img {
width: 80%;
padding: 10%;
}
</style>
</head>
<body>
<img
src="https://img.mukewang.com/5e6af63d00011da318720764.jpg"
alt=""
id="img"
/>
<script>
// 异步加载图片
const loadImgAsync = url => {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img);
};
img.onerror = () => {
reject(new Error(`Could not load image at ${url}`));
};
img.src = url;
});
};
const imgDOM = document.getElementById('img');
loadImgAsync('https://2img.mukewang.com/5f057a6a0001f4f918720764.jpg')
.then(img => {
console.log(img.src);
setTimeout(() => {
imgDOM.src = img.src;
}, 1000);
})
.catch(err => {
console.log(err);
});
</script>
①代码执行loadImgAsync('https://2img.mukewang.com/5f057a6a0001f4f918720764.jpg')时,就会创建img对象,并给img对象赋予具体的src地址:
②此时就会开启网络请求,去网络中某一个具体的位置请求图片,即异步加载图片。图片加载完,就会继续执行如下:
由于图片所在的服务器响应特别快,并且我们的网络特别给力、电脑性能也特别好,因此加载图片这个异步过程会迅速完成,看上去和使用本地图片一样快。但是假设图片所在的服务器响应很慢,那么图片就会很慢的请求回来,举个常见的现象:某些网站,打开后,图片迟迟不展示,此时速度上,就有差异了。
十。如何统一处理错误?Promise参与过程中什么时候会报错?Promise.all等方法返回值是新的promise实例,和传进来的无关;
1.如何统一处理错误:
------------------------------------------------------------------------------------------------------------------------------------------------------
十一。async和await (使得异步操作变得更加方便。)
async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。
调用async
函数时,会立即返回一个Promise
对象。
注意await后面放的是一个可以求值的东西(函数调用等)
等待Promise返回结果: ,如果跟的是promise实例这种情况,会等Promise实例过程中的所有代码全部执行完毕(不论同步异步)如果最终状态为成功态,执行该函数体后面的代码(打印end)
如果最终是失败态实例,该函数体后面的代码(打印end)不会执行且会报错;如果最终是pending状态,该函数体后面的代码(打印end)也不会执行
ES6-Promise下的更多相关文章
- 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise
Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...
- ES6 Promise 接口
构造函数 new Promise(function(resolve, reject){}); 构造函数接受一个函数(executor)作为参数,该函数在返回 Promise 实例之前被调用.函数的两个 ...
- Es6 Promise 用法详解
Promise是什么?? 打印出来看看 console.dir(Promise) 这么一看就明白了,Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方 ...
- ES6 Promise 全面总结
转载:点击查看原文 ES6 Promise对象 ES6中,新增了Promise对象,它主要用于处理异步回调代码,让代码不至于陷入回调嵌套的死路中. @-v-@ 1. Promise本质 Promise ...
- ES6 Promise 异步操作
最近越来越喜欢与大家进行资源分享了,并且及时的同步到自己的园子内,为什么呢? 一.小插曲(气氛搞起) 在上个月末,由于领导的高度重视(haha,这个高度是有多高呢,185就好了),走进了公司骨干员工的 ...
- 微信小程序Http高级封装 es6 promise
公司突然要开放微信小程序,持续蒙蔽的我还不知道小程序是个什么玩意. 于是上网查了一下,就开始着手开发..... 首先开发客户端的东西,都有个共同点,那就是 数据请求! 看了下小程序的请求方式大概和a ...
- 解析ES6 Promise
ES6 Promise 概念之类的,大概读者都应该有所知道,接下来我们直入终点. 先让我们来看看什么是Promise吧,他是一个object,类,arry,function? 首先,学习它的时候应该讲 ...
- ES6 Promise(2)
Promise的兴起,是因为异步方法调用中,往往会出现回调函数一环扣一环的情况.这种情况导致了回调金字塔的出现.不仅代码写起来费劲不美观,而且问题复杂的时候,阅读代码的人也难以理解. db.save( ...
- es6 promise 所见
一.Promise是什么? Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息:从本意上讲,它是承诺,承诺它过一段时间会给你一个结果. pro ...
- 基于Gulp + Browserify构建es6环境下的自动化前端项目
随着React.Angular2.Redux等前沿的前端框架越来越流行,使用webpack.gulp等工具构建前端自动化项目也随之变得越来越重要.鉴于目前业界普遍更流行使用webpack来构建es6( ...
随机推荐
- ROS入门:话题
1.listener.cpp #include "ros/ros.h" #include "std_msgs/String.h" //回调函数,接收到话题后进入 ...
- Technique to Read Source Code
Technique to Read Source Code Excerpted from http://ruby-hacking-guide.github.io/intro.htm Any progr ...
- Vulhub 漏洞学习之:Django
Vulhub 漏洞学习之:Django 目录 Vulhub 漏洞学习之:Django 1 Django debug page XSS漏洞(CVE-2017-12794) 1.1 漏洞利用过程 2 Dj ...
- U-Boot-基础概念与学习分享
U-Boot 基础概念与学习分享 Board: rockchip-px30, armv8, Cortex-A35 U-Boot: rockchip-linux/u-boot, branch next- ...
- 如何用revit+bimfilm快速完成径向动画制作
推荐:将 NSDT场景编辑器 加入你的3D开发工具链. 在实际的施工中,我们会遇到诸如一些管道保温层包覆的施工内容,所以在制作它们的施工动画时,我们需要用径向剖切保温层来表达管道保温层包覆过程的施工状 ...
- RocketMQ - 消费者进度保存机制
RocketMQ设计了远程位点管理和本地位点管理两种位点管理方式.集群消费时,位点由客户端提交给Broker保存,具体实现代码在RemoteBrokerOffsetStore.java文件中:广播消费 ...
- spring boot 配置Bean
package com.example.demo.config; import com.example.demo.entiy.User; import org.springframework.cont ...
- flannel 关闭SNAT
flannel 关闭SNAT 默认情况下,flannel 访问集群外网络是通过 SNAT 成宿主机 ip 方式,在一些金融客户环境中为了能实现防火墙规则,需要直接针对 POD ip 进行进行规则配置, ...
- 预处理指令详解(C语言
一.预处理符号 预处理符号是C语言内置的符号,是可以直接使用的. 其中,若遵顼ANSI C,则__STDC__ 为1,否则未定义. 二.#define 1)定义标识符 define可以用来定义标识符, ...
- ALBERT论文简读
问题描述 预训练自然语言表征时,增加模型的参数量通常可以是模型在下有任务中性能提升.但是这种做法对硬件设备的要求较高(当下的各种SOTA模型动辄数亿甚至数十亿个参数,倘若要扩大模型规模,这个内存问题是 ...