第一次写写分享,文笔不好请见谅,使用的图片来源都是来自网络,如有侵权,请联系删除
最近在研究学习promise,在网上看了很多别人的分享,受益匪浅,然后自己研究,大概有一两天,感觉有了一点眉目。
平时的学习中经常使用到ajax就想自己试着封装一个,既能更熟悉的掌握promise又能对ajax的原理有一个了解觉得还是很值的,而且promise掌握了对后面的async也能够有一个更加清晰的认识!
首先还是先来认识为什么要使用promise吧
要说promise就不得不说以前js异步解决方法 -> 回调 ;回调这个东西解决了js没有异步的问题,让以前的前辈又多了一种解决问题的办法;
但是同时也出现了一个新的问题即回调地狱,网上有一张生动形象的图片
造成代码不美观(毕竟程序猿也是爱美之人吗),别人阅读起来也很难受😫
于实promise出现了,勉强解决了这种回调地狱的现象(以下这些好处总结来自百度🤭),
promise将复杂的异步处理操作简单化
让代码更具有可读性
解决异常更方便
还能链式操作
Promise的语法使用
将以往的异步回调形式改写为更加直观的promise形式举个简单的例子
let str = "hello";
function say(fn) {
setTimeout(() => {
fn(str);
}, 100);
}
say(str => {
console.log(str);
});
将这样一个简单个回调改写为promise形式的
经过简单的修改
let str = "hello";
let say = new Promise((res, rej) => {
setTimeout(() => {
res(str);
}, 100);
}).catch(e => {});
say.then(str => {
console.log(str);
});
现在你可能跟我有差不多的感受了,觉得回调和promise没有什么区别,其实大部分人才接触都有这种感觉那是因为上面局的栗子都是比较简单的,当遇到业务逻辑复杂,代码量大的时候,我相信你会爱上promise的!
说一下普通回调函数改写为promise的过程
首先和上面的说的一样你的先有一个promise对象,这个对象可以和上面一样赋值给一个引用,或者和后面封装ajax一样作为一个返回值。
然后为这个promise传入一个function作为参数,这个function里面又接受两个参数,第一个通常是当promise顺利完成时的处理办法,第二个就是出现异常时的处理了即
javascript new Promise(function (resolve,reject) { //do something})
然后在这个promise里面经行相关的业务操作,就是 do something了。
在业务操作中在合适的地方将成功的数据穿个function的第一个参数,预想到会失败时就将失败的信息传给function的第二个参数
new Promise(function (resolve,reject) {
//do something
// if succeed
resolve(data)
// if failed
reject(error)
}).catch(e =>{})
最后最好在catch一下
使用promise封装ajax
如果你已经掌握了上面的promise并且你对ajax的原理有一些了解的话那么接下来的活儿,将会很轻松🤭;
ajax的原理时js的XMLHttpResquest()对象,ie7以下是ActiveXObject('Microsoft.XMLHTTP')现在好像很少会考虑兼容到ie7以下了
之后就是这对象上的一些方法使用了,原理不是很难
下面是我的封装,代码里面都有注释,其中options是ajax的配置参数(json形式的),必须传入url,否则不会发出请求,默认是GET请求方式,异步处理,这里还有一个美中不足的地方就是get请求是通过url发送的也就是需要一个对请求的数据url化。
function ajax(options) {
//这个options时传入给ajax的配置参数
return new Promise((resolve, reject) => {
//返回一个promise对象 resolve成功是的处理,reject失败时的处理
if (!options.url) { // 需要请求的路径
console.log("请确认你的url路径");
return;
}
let method = options.method || "GET"; //请求方式如果没有就默认为get
let async = options.async || true; //ajax是否异步请求默认位true
let xhr = new XMLHttpRequest();
if (method === "GET") {
xhr.open(method, options.url + "?" + Math.random(), async); //防止缓存
xhr.send(null);
} else if (method === "POST") {
xhr.open(method, options.url, async);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(options.data);
}
// xhr.responseType = options.type || "";
xhr.onreadystatechange = () => {
if (xhr.responseText) {
//有数据说明相应成功
resolve(xhr.responseText);
}
};
xhr.onerror = err => {
reject(err);
};
}).catch(e => {});
}
以上就是我的封装了,可以直接拿去用,当然如果上面的封装有什么问题可以联系我,毕竟我也是学习的人,大家一起学习,一起进步🤭