目录
前言
fetch 是用来替代传统的XMLHttpRequest
的。 fetch 的优点很多,包括链式调用的语法、返回promise等。
什么是Promise?
当在开发中需要处理异步操作时,Promise是一个常用的工具。Promise是一个表示异步操作最终完成或失败的对象。
创建一个Promise对象时,可以传入一个执行器函数,该函数接受两个参数:resolve 和 reject 。通过调用resolve函数,表示异步操作成功并传递结果,而调用reject函数表示异步操作失败并传递错误信息。
以下是一个使用Promise的简单示例:
// 创建一个简单的异步操作
const fetchData = () => {
return new Promise((resolve, reject) => {
// 模拟异步操作,比如从服务器获取数据
setTimeout(() => {
const data = {id: 1, name: 'John'};
if (data) {
resolve(data); // 异步操作成功
} else {
reject('Failed to fetch data.'); // 异步操作失败
}
}, 2000);
});
};
// 使用Promise处理异步操作
fetchData()
.then(data => {
console.log('异步操作成功:', data);
// 在这里可以对获取的数据进行处理
})
.catch(error => {
console.log('异步操作失败:', error);
// 在这里可以处理异步操作失败的情况
});
在上面的示例中,fetchData 函数返回一个 Promise 对象,通过调用 resolve 和 reject 函数来表示异步操作的结果。然后可以使用.then()
来处理异步操作成功的情况,并使用.catch()
来处理异步操作失败的情况。
当异步操作成功时,.then()
中的回调函数会被调用,并将异步操作的结果传递给它。当异步操作失败时,.catch()
中的回调函数会被调用,并将错误信息传递给它。
这只是Promise的基本用法,还可以使用更多的方法和技巧来处理Promise,例如使用Promise.all()
来处理多个异步操作,使用async/await
来编写更简洁的异步代码等。
测试示例
// 使用示例1
new Promise(function (resolve, reject) {
var a = 0;
var b = 1;
if (b == 0) {
// 触发catch块中的逻辑
reject("除零错误");
} else {
// 触发then块中的逻辑
resolve(a / b);
}
}).then(function (value) {
// 由resolve触发
console.log("a / b = " + value);
}).catch(function (err) {
// 由reject触发
console.log(err);
}).finally(function () {
// 无论如何要执行的语句
console.log("最后finally块中的代码");
});
// 使用示例2
new Promise(function (resolve, reject) {
console.log(1);
resolve(2);
}).then(function (value) {
console.log(value);
return 3;
}).then(function (value) {
console.log(value);
throw "抛出错误";
}).catch(function (err) {
console.log(err);
});
为什么用fetch?
fetch 官网:https://github.com/github/fetch
fetch
是 JavaScript 提供的一种现代化的网络请求 API,用于进行网络请求并获取资源。它是基于 Promise 的,使用起来相对简单和灵活。
传统的 xhr 请求写起来非常的混乱,如下所示:
例1:
var xhr = new XMLHttpRequest();
xhr.open('GET', "https://api.github.com");
xhr.responseType = 'json';
// 设置成功回调
xhr.onload = function() {
console.log(xhr.response);
};
// 设置错误回调
xhr.onerror = function() {
console.log("请求发生错误!");
};
// 发送请求
xhr.send();
例2:
// 需要目标站点后台服务器给响应头设置允许跨域的标识头
function sendAjax() {
var req = new XMLHttpRequest();
req.open('GET', "https://api.github.com");
req.send();
// 设置成功回调
req.onreadystatechange = function () {
if (req.readyState === 4) {
try {
alert(req.responseText);
b = req.response;
} catch (e) {
alert('你访问的页面出错了');
}
}
};
// 设置请求超时回调
req.ontimeout = function () {
console.log("请求超时")
}
}
sendAjax()
但使用 fetch 之后,如下所示:
fetch("https://api.github.com")
.then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("请求发生错误!"));
在上面的示例中,使用 fetch
函数来发起一个 GET 请求,并传递目标 URL 作为参数。fetch
返回一个 Promise 对象,我们可以使用 .then()
来处理请求成功的情况,通过 .catch()
来处理请求失败的情况。
在第一个 .then()
中,我们使用 response.json()
方法将响应数据解析为 JSON 格式。这个方法也返回一个 Promise 对象,我们可以再次使用 .then()
来处理解析后的数据。
如果需要发送 POST 请求或者设置其他请求参数,fetch
还提供了相应的选项。下面是一个带有 POST 请求和请求头设置的示例:
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({username: 'john', password: 'secret'})
})
.then(response => response.json())
.then(data => {
console.log('获取到的数据:', data);
// 在这里可以对获取到的数据进行处理
})
.catch(error => {
console.log('请求失败:', error);
// 在这里可以处理请求失败的情况
});
在上面的示例中,通过传递第二个参数来设置请求选项。method
设置为 'POST'
表示发送一个 POST 请求,headers
设置了请求头的 'Content-Type'
为 'application/json'
,body
是一个包含要发送的数据的对象,并使用 JSON.stringify
将其转换为 JSON 字符串。
使用 fetch
进行网络请求的优势之一是可以与其他 JavaScript 特性(如 async/await
、Promise.all
)结合使用,从而编写更简洁和灵活的代码。
async、await
async
和 await
是 JavaScript 中用于处理异步操作的关键字。它们可以用更简洁、更易读的方式编写异步代码。
async
关键字用于定义一个异步函数,异步函数内部可以包含 await
关键字。异步函数在被调用时会返回一个 Promise 对象,该对象会在异步操作完成时解析为返回值。
下面是一个简单的示例,展示了如何使用 async
和 await
:
// 异步函数
async function fetchData() {
// 模拟异步操作,比如从服务器获取数据
const response = await fetch('https://api.github.com/users/mzabriskie');
const data = await response.json();
return data;
}
// 使用异步函数
async function processData() {
try {
const result = await fetchData();
console.log('异步操作成功:', result);
// 在这里可以对获取的数据进行处理
} catch (error) {
console.log('异步操作失败:', error);
// 在这里可以处理异步操作失败的情况
}
}
// 调用异步函数
processData();
在上面的示例中,fetchData
是一个异步函数,内部使用了 await
关键字来等待异步操作的结果。fetch
函数返回一个 Promise 对象,使用 await
等待该 Promise 对象解析为结果。类似地,response.json()
也返回一个 Promise 对象,也需要使用 await
等待结果。
在 processData
函数中,我们使用 try...catch
来捕获可能发生的错误。如果异步操作成功,await
表达式会返回异步操作的结果,并将其赋值给 result
变量。如果异步操作失败,会抛出一个错误,被 catch
块捕获并进行处理。
总结一下,async
关键字用于定义异步函数,await
关键字用于等待异步操作的结果。它们的使用可以让异步代码更加清晰、易读,并且可以使用类似同步代码的方式进行编写。
- 异步执行验证:最后打印的时间相差在1秒内即为异步执行
async function test() {
let b = 0;
for (let i = 0; i < 100000000; i++) {
b++;
}
console.log(b)
console.log(new Date())
}
for (var i = 0; i < 10; i++) {
test()
}
- 异步请求示例
// async function
async function fetchAsync() {
// await response of fetch call
let response = await fetch('https://api.github.com');
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
return data;
}
// trigger async function
// log response or catch error of fetch promise
fetchAsync()
.then(data => console.log(data))
.catch(e => console.log(e.message))
基本使用方法
fetch 必须接受一个资源路径作为参数,并且返回了一个promise,所以我们可以直接使用链式调用的方式。
ajax请求
fetch("/getAllUserInfo")
.then(res => res.json())
.then(data => {
if (data.code === 200) {
console.log('获取所有用户信息', data.data);
// 其它业务逻辑
} else {
console.log(data.message);
}
})
自定义请求
fetch 提供了对 Request 和 Response (以及其他与网络请求有关的)对象的通用定义。所以在一个Fetch请求中,完全可以只使用Request 和 Response两个对象,通过Request 设置参数,通过Response 对返回值进行处理。
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'image/jpeg');
var option = {
method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default'
};
var myRequest = new Request('https://api.github.com/users/mzabriskie', option);
fetch(myRequest).then(response => {
console.log(response)
return response.json()
}).then(data => console.log(data));
HTML请求
fetch('/users.html')
.then(function(response) {
return response.text()
}).then(function(body) {
document.body.innerHTML = body
})
JSON请求
fetch('/users.json')
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
Response metadata
fetch('/users.json').then(function(response) {
console.log(response.headers.get('Content-Type'))
console.log(response.headers.get('Date'))
console.log(response.status)
console.log(response.statusText)
})
Post form
var form = document.querySelector('form')
fetch('/users', {
method: 'POST',
body: new FormData(form)
})
Post JSON
fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Hubot',
login: 'hubot',
})
})
File upload
var input = document.querySelector('input[type="file"]')
var data = new FormData()
data.append('file', input.files[0])
data.append('user', 'hubot')
fetch('/avatars', {
method: 'POST',
body: data
})
注意点
1、 fetch api 提供的spi囊括但是不限于xhr的所有功能。
2、 fetch api 可以跨域,参考: https://fetch.spec.whatwg.org/#http-cors-protocol
要求响应对象的header
中必须含有Access-Control-Allow-origin
允许跨域的标识
在发送 fetch 请求的时候就会使用到CORS协议,尽管这些对于开发者来说是透明的,但是浏览器还是会发送 origin 字段。
标签:异步,console,log,编程,JS,response,data,fetch From: https://www.cnblogs.com/hhddd-1024/p/17456520.html