上面提到第 1 种方法中有一点需要特别注意

时间:2022-02-28 06:48:39

Ajax 和异步措置惩罚惩罚

挪用 API 访谒数据给与的 Ajax 方法,这是一个异步过程,异步过程最根基的措置惩罚惩罚方法是事件或回调,其实这两种措置惩罚惩罚方法实现道理差不久不多,都需要在挪用异步过程的时候传入一个在异步过程结束的时候挪用的接口。好比 jQuery Ajax 的 success 就是范例的回调参数。不过使用 jQuery 措置惩罚惩罚异步保举使用 Promise 措置惩罚惩罚方法。

Promise 措置惩罚惩罚方法也是通过注册回调函数来完成的。jQuery 的 Promise 和 ES6 的标准 Promise 有点不一样,但在 then 上可以兼容,凡是称为 thenable。jQuery 的 Promise 没有供给 .catch() 接口,但它本身界说的 .done()、.fail() 和 .always() 三个注册回调的方法也很有特色,用起来很便利,它是在事件的方法来注册的(即,可以注册多个同类型的措置惩罚惩罚函数,在该触发的时候城市触发)。

固然更直不雅观的一点的措置惩罚惩罚方法是使用 ES2017 带来的 async/await 方法,可以用同步代码的形式来写异步代码,固然也有一些坑在里面。对付前端工程师来说,最大的坑就是有些浏览器不撑持,需要进行转译,所以如果前端代码没有构建过程,一般还是就用 ES5 的语法兼容性好一些(jQuery 的 Promise 是撑持 ES5 的,,但是标准 Promise 要 ES6 以后才可以使用)。

关于 JavaScript 异步措置惩罚惩罚相关的内容可以参考

本身封装工具函数

在措置惩罚惩罚 Ajax 的过程中,虽然有现成的库(好比 jQuery.ajax,axios 等),它终究是为了通用目的设计的,在使用的时候仍然难免繁琐。而在项目中,对 Api 进行挪用的过程几乎都大同小异。如果设计恰当,就连错误措置惩罚惩罚的方法城市是一样的。因此,在项目内的 Ajax 挪用其实可以进行进一步的封装,使之在项目内使用起来更便利。如果接口方法产生变革,改削起来也更容易。

好比,当前接口要求使用 POST 要领挪用(暂不考虑 RESTful),参数必需包孕 action,返回的数据以 JSON 方法供给,如果堕落,只要不是处事器异常城市返回特定的 JSON 数据,包孕一个不即是 0 的 code 和可选的 message 属性。

那么用 jQuery 写这么一个 Ajax 挪用,概略是这样

const apiUrl = ""; jQuery .ajax(url, { type: "post", dataType: "json", data: { action: "login", username: "uname", password: "passwd" } }) .done(function(data) { if (data.code) { alert(data.message || "登录掉败!"); } else { window.location.assign("home"); } }) .fail(function() { alert("处事器错误"); }); 初阶封装

同一项目中,这样的 Ajax 挪用,根基上只有 data 部分和 .done 回调中的 else 部分差别,所以进行一次封装会大大减少代码量,可以这样封装

function appAjax(action, params) { var deffered = $.Deferred(); jQuery .ajax(apiUrl, { type: "post", dataType: "json", data: $.extend({ action: action }, params) }) .done(function(data) { // 当 code 为 0 或省略时,暗示没有错误, // 其它值暗示错误代码 if (data.code) { if (data.message) { // 如果处事器返回了动静,那么向用户泛起动静 // resolve(null),暗示不需要后续进行业务措置惩罚惩罚 alert(data.message); deffered.resolve(); } else { // 如果处事器没返回动静,那么把 data 丢给外面的业务措置惩罚惩罚 deferred.reject(data); } } else { // 正常返回数据的情况 deffered.resolve(data); } }) .fail(function() { // Ajax 挪用掉败,向用户泛起动静,同时不需要进行后续的业务措置惩罚惩罚 alert("处事器错误"); deffered.resolve(); }); return deferred.promise(); }

而业务层的挪用就很简单了

appAjax("login", { username: "uname", password: "passwd" }).done(function(data) { if (data) { window.location.assign("home"); } }).fail(function() { alert("登录掉败"); }); 改换 API 挪用接口

上面的封装对挪用接口和返回数据进行了统一措置惩罚惩罚,把大部分项目接口约定的内容都措置惩罚惩罚失了,剩下在每次挪用时需要措置惩罚惩罚的就是纯粹的业务。

此刻项目组决定不用 jQuery 的 Ajax,而是给与 axios 来挪用 API(axios 不见得就比 jQuery 好,这里只是举例),那么只需要改削一下 appAjax() 的实现即可。所有业务挪用都不需要改削。

假设此刻的方针环境仍然是 ES5,那么需要第三方 Promise 供给,这里拟用 Bluebird,兼容原生 Promise 接口(在 HTML 中引入,未直接呈此刻 JS 代码中)。

function appAjax(action, params) { var deffered = $.Deferred(); axios .post(apiUrl, { data: $.extend({ action: action }, params) }) .then(function(data) { ... }, function() { ... }); return deferred.promise(); }

此次的封装给与了 axios 来实现 Web Api 挪用。但是为了连结本来的接口(jQuery Promise 东西有供给 .done()、.fail() 和 .always() 事件措置惩罚惩罚),appAjax 仍然不得不返回 jQuery Promise。这样,即使所有处所都不再需要使用 jQuery,这里仍然得用。

项目中应该用还是不用 jQuery?请阅读为什么要用原生 JavaScript 取代 jQuery? 去除 jQuery

就只在这里使用 jQuery 总让人觉得如芒在背,想把它去失。有两个步伐