1.promise
1.1promise 概念
- promise是异步编程的一种解决方案,比传统的解决方案–回调函数和事件,更合理和强大。
- 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
- 从语法上说,promise是一个对象,从他可以获取异步操作的消息。promise提供统一的API,各种异步操作都可以用同样的方法进行处理。
1.2promise 的特点
有且只有两种,而且一个promise对象只能改变一次,无论变为成功还是失败,都会有一个结果数据,成功的结果数据一般为value,失败的数据结果一般被称为reason。
- 操作成功:pending—> fulfilled/resolved、
- 操作失败:pending—> rejected
异步回调嵌套
promise
参数一:resolve参数:带出返回成功的值
参数二: reject参数:带出返回响应失败的值
ES6规定:promise对象是一个构造函数,用来生成promise实例。通过在函数内部return一个promise对象的实例,这样就可以使用promise的属性和方法进行下一步操作了。
1.3 promise 的方法
- hen() 方法就是把原来的回调写法分离出来,在异步操作完成后,用链式调用的方式执行回调函数。
.then() 有两个 参数 (两个参数是两个函数,第一函数是成功的结果值,第二个函数是失败的结果值)
then()的第一个参数代表捕捉成功的结果的函数
then()的第二个参数代表捕捉失败的结果的函数 - catch() 和then() 方法一样,都会返回一个新的promise对象,它主要用于捕获异步操作时出现的异常。
- all() promise包含n个promise的数组,说明:返回一个新的promise,只有promise都成功才成功,只要有一个失败就都失败。
- race:第一个完成的promise的结果状态就是最终的结果状态
// promise方法
var p = new Promise(function(resolve){
setTimeout(function(){
resolve('吃火锅')
},2000)
}).then(ele=>{
console.log(ele);
return getLai();
}).then(ele=>{
console.log(ele);
})
将ajax转化为promise的形式:
function promise(options){
return new Promise((resolve,reject)=>{
var xhr = new XMLHttpRequest();
var params = formdata(options.data);
if(options.type=='GET'){
xhr.open(options.type,options.url+'?'+params,options.isAsync);
xhr.send();
}
if(options.type=='POST'){
xhr.open(options.type,options.url,options.isAsync);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(params);
}
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status==200){
resolve(xhr.responseText)
}else{
reject('错误')
}
}
}
})
}
function formdata(obj){
var arr = [];
for(var k in obj){
arr.push(k+'='+obj[k])
}
return arr.join('&')
}
调用:
promise({
type:'GET',
url:'',
date:{},
isAsync:true,
}).then(data=>{
console.log(data);
return promise({
type:'GET',
url:'',
data:{},
isAsync:true,
})
}).then(data=>{})
2-1.jsonp
2.1 什么叫同源
如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
http://www.example.com/dir/page.html
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
https://www.example.com/dir/page.html:不同源(协议不同)
2.2什么叫同源策略
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。
2.3同源策略的目的
同源策略是为了保护用户信息的安全,防止恶意的网站窃取数据。
2-2jsonp跨域
jsonp的原理:页面上有很多标签比如src, href, 都不会受到同源策略的影响。
有一些标签天生就有跨域能力,如:img , link , iframe , script
jsonp就是利用
jsonp 由两部分组成:回调函数和数据,回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的JSON数据
- 将不同源的服务器端请求地址写在 script 标签的 src 属性中
<script src="www.example.com"></script>
- 服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。
const data = 'fn({name: "张三", age: "20"})';
- 在客户端全局作用域
function fn(data){}
- 在fn函数内部对服务器端返回的数据进行处理
整体实现思路:
- 客户端需要将函数名称传递到服务器端
- 将script请求的发送变成动态的请求。
function jsonp(options){ var oSc = document.createElement('script'); oSc.src = options.url; document.body.appendChild(oSc); oSc.onload = function(){ this.remove(); }}
jsonp的封装
function jsonp(options){
// 创建script
var oSrc = document.createElement('script');
// window[fn]:将fn函数挂载在全局作用域下
// 将传入的函数转为window对象下
var fn = 'myfn' + Math.random().toString().replace('.','');
// fn随机函数名
window[fn] = options.success;
oSrc.src = options.url+'?callback='+fn+'&'+getParams(options.data);
document.body.appendChild(oSrc);
oSrc.onload = function(){
this.remove();
}
}
function getParams(obj){
var arr = [];
for(var k in obj){
arr.push(k+'='+obj[k]);
}
return arr.join('&')
}