Appearance
前端发送网络请求
axios
返回 Promise 对象,支持链式调用,可以使用 .then() 和 .catch() 等方法处理响应。
取消请求
// 第一种方式
const CancelToken = axios.CancelToken
const source = CancelToken.source()
axios.get('xxx', {
cancelToken: source.token,
responseType: 'json', // text blob arraybuffer
}).then(response => {
console.log(response.data)
}).catch(function (thrown) {
// 判断是否是取消请求
if (axios.isCancel(thrown)) {
console.log('请求被取消:', thrown.message)
} else {
}
});
source.cancel('主动取消请求')
// 第二种方式
const CancelToken = axios.CancelToken
let cancel
axios.get('xxxx', {
cancelToken: new CancelToken(function executor(c) {
cancel = c
})
})
cancel('取消接口避免重复调用')// 允许跨域时携带凭证 cookies
// 服务器必须在响应头中明确允许特定来源
axios.defaults.withCredentials = truefetch
浏览器原生方法
// 创建 AbortController 实例
const controller = new AbortController();
const signal = controller.signal;
fetch('https://www.test.com/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data),
signal: signal,
// keepalive: true, // 会在页面卸载后继续发送异步请求(请求大小限制大约64KB)
// mode: 'cors', // 发送带有CORS头部的请求
credentials: 'include' // omit same-origin include
})
.then(response => {
if (response.ok) {
return response.json()
}
throw new Error('Network response was not ok.')
})
.then(data => console.log(data))
.catch(error => {
if (error.name === 'AbortError') {
console.log('Fetch aborted') // 处理取消的情况
} else {
console.error('Fetch error:', error) // 处理其他错误
}
})
// controller.abort() // 取消请求XHR
// 封装一个ajax请求
function ajax(options) {
// 创建XMLHttpRequest对象
const xhr = new XMLHttpRequest()
options = options || {}
options.type = (options.type || 'GET').toUpperCase()
options.dataType = options.dataType || 'json'
const params = options.data
// 发送请求
if (options.type === 'GET') {
xhr.open('GET', options.url + '?' + params, true)
xhr.send(null)
} else if (options.type === 'POST') {
xhr.open('POST', options.url, true)
xhr.send(params)
}
// 接收请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
let status = xhr.status
if (status >= 200 && status < 300) {
options.success && options.success(xhr.responseText, xhr.responseXML)
} else {
options.fail && options.fail(status)
}
}
}
}使用方式:
ajax({
type: 'post',
dataType: 'json',
data: {},
url: 'https://xxxx',
success: function(text,xml) {
console.log(text)
},
fail: function(status) {
console.log(status)
}
})Promise
Promise就是为了解决回调地狱而产生的,将回调函数的嵌套,改成链式调用。
状态
pending 进行中
fulfilled 已完成
rejected 已失败
实例方法
then()
catch()
finally()
静态方法
Promise.resolve(): 返回一个 fulfilled 状态的 Promise
Promise.reject(): 返回一个 rejected 状态的 Promise
Promise.all(): 所有Promise都成功
Promise.allSettled(): 所有Promise都完成(无论成功失败)
Promise.any(): 返回最先成功的 Promise 的结果
Promise.race(): 返回最先完成的 Promise 的结果
async/await
async/await 是 Promise 的语法糖,将异步代码以同步的形式进行编写。
const asyncReadFile = async function () {
try {
const f1 = await readFile('/etc/file1');
const f2 = await readFile('/etc/file2');
console.log(f1.toString());
console.log(f2.toString());
} catch(error) {
console.log('try catch 是同步执行的,这里可以捕捉到错误', error)
}
}Generator
yield 表达式可以暂停函数执行,next方法用于恢复函数执行,这使得 Generator 函数非常适合将异步任务同步化。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator()
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true