ajax.js(来自项目)学习笔记
一、学习资料
1、axios:一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端

特点:
从浏览器中创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF
2、qs: node.js的QueryString模块

·作用是解析和格式化URL查询字符串,即对http请求所带的数据进行解析和格式化。
·只提供四个方法
1)querystring.parse(str[, separator[, eq[, options]]]) 将一个字符串反序列化为一个对象
str<string>要解析的URL查询字符串sep<string>用于在查询字符串中分隔键和值对的子字符串。默认为'&'。eq<string>。用于分隔查询字符串中的键和值的子字符串。默认为'='。options<对象>- o
decodeURIComponent<function>在查询字符串中解码百分比编码字符时使用的函数。默认为querystring.unescape()。 - o
maxKeys<number>指定要解析的最大键数。默认为1000。指定0删除键盘计数限制。
- o
querystring.parse()方法将URL查询字符串(str)解析为键值对的集合。
例如,查询字符串'foo=bar&abc=xyz&abc=123'被解析为:

2)querystring.stringfy(obj[, separator[, eq[, options]]]) 将一个对象序列化为一个字符串
obj<Object>要序列化为URL查询字符串的对象sep<string>用于在查询字符串中分隔键和值对的子字符串。默认为'&'。eq<string>。用于分隔查询字符串中的键和值的子字符串。默认为'='。options- o
encodeURIComponent<function>在查询字符串中将URL不安全字符转换为百分比编码时使用的函数。默认为querystring.escape()。
- o
该querystring.stringify()方法obj通过遍历对象的“自己的属性” 从给定的URL中产生一个URL查询字符串。
例子:

3)querystring.escape(str) 对传入的字符串进行编码
例子:

4)querystring.unescape(str) 对可能含有%的字符串进行解码
例子:

3、Process:node.js的一个模块,提供有关信息,控制当前node.js的进程。事实上是nodejs中的一个全局变量,因此使用的时候无需require()。
Process.env返回一个包含用户环境信息的对象。

4、axios.create()通过自定义配置新建一个axios的实例。

1)baseurl:baseurl将自动加在url前面,除非url是一个绝对url。它可以通过设置一个baseurl便于为axios实例的方法传递相对url。
2)timeout:请求超时的毫秒数,如果请求花费超过了timeout的时间,请求将被中断。
3)header:被发送的自定义请求头
·Content-Type代表发送端发送的实体数据的数据类型。
application/x-www-form-urlencoded是最常见的post提交数据的方式,提交的数据按照键值对key1=val1&key2=val2的方式进行编码
·Accept代表发送端(客户端)希望接受的数据类型。
application/json客户端接受服务端json格式的数据。
· If-Modified-Since
Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since 则是由客户端往服务器发送的头。再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。
5、只读函数get:

axios实例的get方法:axios.get(url[ ,config ])
·url<string> 用于请求的服务器url
·config <obj> 创建请求时的配置选项,可在https://www.kancloud.cn/yunye/axios/234845详细查看
函数里设置创建请求的配置选项,包括params(即将与请求一起发送的url参数)和请求超时的时间。
配置过程:请求时发送的数据不为空,对象params的属性params(params是即将与请求一起发送的url参数)就等于data,timeout不为0,params的属性timeout就等于timeout。
axios的get请求返回的也是一个promise对象,跟踪对象只要后面加一个catch方法就好了。
6、 只读函数post:

axios实例的post方法:axios.post(url[ ,data[ ,config ]])
·url<string> 用于请求的服务器url
·config <obj> 创建请求时的配置选项,可在https://www.kancloud.cn/yunye/axios/234845详细查看
函数里设置post发送的数据和创建请求的配置选项,包括请求超时的时间。
axios的post请求返回的也是一个promise对象,跟踪对象只要后面加一个catch方法。
7、 promise的作用与回调方法(callback)一样,都是在某种情况下执行设定好的方法。但promise的多重链式调用能使代码更整洁,避免出现“回调地狱”(回调嵌套太多层)。在es6中,promise成为了原生对象可以直接使用。
Ajax请求的传统写法:

改为promise写法:

很显然,promise的写法把异步调用中使用回调函数的场景改为了.then()、.catch()等函数链式调用的方式,基于promise可以把复杂的异步调用方式进行模块化。
Promise的原理分析:
Promise对象共有三个状态,分别是:
·pending(进行中)
·resolved(已完成,又称为fullfilled)
·rejected(已失败)
由异步操作的结果决定当前是什么状态。状态的改变只有两种可能:
·从pending变为fullfilled
·从pending变为rejected
只要这两种情况发生,状态就不会再改变了,因此状态是不能逆向改变的。
构建promise:

Promise的构造函数接受一个函数作为参数,该函数的两个参数分别为resolve和reject两个函数。
·Resolve函数将promise对象的状态由pending变为resolved,异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
·reject函数将状态由pending变为rejected,异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise的实例方法:
Promise对象拥有两个实例方法then()和catch()。
·then()方法接受两个函数作为参数,第一个是状态变为resolved时调用,第二个则是状态变为rejected是调用,第二个函数是可选的。
Promise实例生成以后,可以用then方法指定resolved状态和rejected状态的回调函数,即成功和失败的回调函数。
promise构造函数中通常都是异步的,所以then方法往往都先于resolve和reject方法执行。这两个函数作为成功和失败的回调函数,都接受promise对象传出的值作为参数。

then()方法将返回一个新的promise。
因此then可以链式调用,在新的对象上添加失败或成功的回调。
·catch()方法的作用是捕获promise的错误。
与then()方法的rejected回调作业几乎一致。
我们知道,如果 Promise 状态已经变成resolved,再抛出错误是无效的。

上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
由于promise对象的错误会一直向后传递,直到被捕获,即错误总会被下一个catch所捕获。then方法指定的回调函数,若抛出错误,也会被下一个catch捕获。catch中也能抛错,则需要后面的catch来捕获。

一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。
这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不使用then()的rejected回调,而是统一使用catch()来处理错误。
跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应。Promise 内部的错误不会影响到 Promise 外部的代码。
二、总结
Ajax.js的流程(过程):
1、创建axios的实例
const instance = axios.create({ baseURL: baseUrl, timeout: 20000, headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json', 'If-Modified-Since': '0' } });
2、封装axios实例的get和post方法:
若执行只读函数get()或post():
1)分别发送get请求和post请求
2)用catch捕获错误和处理错误,
3)返回一个新的promise实例。
const get = (url, data, timeout) => { let params; if (data) { params = { params: data }; } if (timeout) { params.timeout = timeout; } return instance .get(url, params) .catch(handleError); }; const post = (url, data, timeout) => { data = qs.stringify(data); const config = { timeout }; return instance .post(url, data, config) .catch(handleError); };
3、封装get和post的接口:
若执行getAPI()或者postAPI(),会返回一个promise实例,生成该promise实例的构造函数做了除了返回一个新的promise实例以外的以下几件事情:
1)分别执行了封装好的get()方法和post()方法
2)利用promise的then()方法指定了get()或者post()成功以后调用的回调函数resolve(response.data)
const getApi = (url, data, timeout) => { return new Promise((resolve, reject) => { get(url, data, timeout) .then(response => { resolve(response.data); }); }); }; const postApi = (url, data, timeout) => { return new Promise((resolve, reject) => { post(url, data, timeout) .then(response => { resolve(response.data); }); }); };
三、参考文档
ECMAScript 6 入门
http://es6.ruanyifeng.com/#docs/promise#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95
初探promise
https://segmentfault.com/a/1190000007032448
Axios 中文说明
https://www.kancloud.cn/yunye/axios/234845
Node.js v9.40文档
https://nodejs.org/api/querystring.html

浙公网安备 33010602011771号