大概内容
Fetch API 和 XMLHttpRequest
Ajax
then()方法
promise
- 目的
从服务端获取个别数据来更新部分网页而不用加载整个页面。 - Ajax开始
这导致了创建允许网页请求小块数据(例如 HTML, XML, JSON, 或纯文本) 和 仅在需要时显示它们的技术,从而帮助解决上述问题。
这是通过使用诸如 XMLHttpRequest 之类的API或者 — 最近以来的 Fetch API 来实现.
这些技术允许网页直接处理对服务器上可用的特定资源的 HTTP 请求,并在显示之前根据需要对结果数据进行格式化。
Ajax模型包括使用Web API作为代理来更智能地请求数据,而不仅仅是让浏览器重新加载整个页面。
为了进一步提高速度,有些网站还会在首次请求时将资产和数据存储在用户的计算机上,这意味着在后续访问中,他们将使用本地版本,而不是在首次加载页面时下载新副本。 内容仅在更新后从服务器重新加载。
画两遍这个图,对这块学习好像挺有帮助
Fetch API 的简单例子
Fetch API基本上是XHR的一个现代替代品——它是最近在浏览器中引入的,它使异步HTTP请求在JavaScript中更容易实现,对于开发人员和在Fetch之上构建的其他API来说都是如此。
Fetch API提供了一个JS的接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局fetch90方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
这种功能以前是使用 XMLHttpRequest实现的。Fetch提供了一个更好的替代方法,可以很容易地被其他技术使用,例如 Service Workers。Fetch还提供了单个逻辑位置来定义其他HTTP相关概念,例如CORS和HTTP的扩展。
- 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP
响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok
属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
下面例子的txt文件自己随便写内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>Basic XHR example</title>
<style>
html, pre {
font-family: sans-serif;
}
body {
width: 500px;
margin: 0 auto;
background-color: #ccc;
}
pre {
line-height: 1.5;
letter-spacing: 0.05rem;
padding: 1rem;
background-color: white;
}
label {
width: 200px;
margin-right: 33px;
}
select {
width: 350px;
padding: 5px;
}
</style>
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<h1>Basic XHR example</h1>
<form>
<label for="verse-choose">Choose a verse</label>
<select id="verse-choose" name="verse-choose">
<option>Verse 1</option>
<option>Verse 2</option>
<option>Verse 3</option>
<option>Verse 4</option>
</select>
</form>
<h2>The Conqueror Worm, <em>Edgar Allen Poe, 1843</em></h2>
<pre> </pre>
<script>
//定义一个onchange函数,在selest值改变时,将其改变的值传递给updateDisplay()函数作为参数
let verseChoose = document.querySelector('select');
let poemDisplay = document.querySelector('pre');
verseChoose.onchange = function() {
let verse = verseChoose.value;
updateDisplay(verse);
};
function updateDisplay(verse) {
//将Verse 1改为verse1.txt的格式
verse = verse.replace(" ", "");
verse = verse.toLowerCase();
let url = verse + '.txt';
//先调用了fetch方法,将我们要获取的资源的url传递给他
//相当于XHR中的request.open()
//然后 .then方法连接到了fetch末尾,这个方法是promises的一部分,用于执行异步操作的现代js特性
//fetch()返回一个promise,他将解析从服务器发回的响应
//我们使用then()来运行一些后续代码,这时在其内部定义函数
//当fetch()promise解析时,,这个函数会自动将响应从服务器传递给参数
//在函数内部,我们获取响应并运行其text方法,这基本上将响应作为原始文本返回
fetch(url).then(function(response){
response.text().then(function(text){
poemDisplay.textContent=text;
});
});
};
updateDisplay('Verse 1');
verseChoose.value = 'Verse 1';
</script>
</body>
</html>
then()方法
then() 方法返回一个 Promise 。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。
let promise1 = new Promise(function(resolve, reject) {
resolve('Success!');
});
promise1.then(function(value) {
console.log(value);
// expected output: "Success!"
});
注意:
如果忽略针对某个状态的回调函数参数,或者提供非函数 (nonfunction) 参数,
那么 then 方法将会丢失关于该状态的回调函数信息,但是并不会产生错误。
如果调用 then 的 Promise 的状态(fulfillment 或 rejection)发生改变,但是 then 中并没有关于这种状态的回调函数,
那么 then 将创建一个没有经过回调函数处理的新 Promise 对象,这个新 Promise 只是简单地接受调用这个 then 的原 Promise 的终态作为它的终态。
语法
p.then(onFulfilled, onRejected);
p.then(function(value) {
// fulfillment
}, function(reason) {
// rejection
});
参数解释
onFulfilled
当Promise变成接受状态(fulfillment)时,该参数作为回调函数被调用(参考: Function)。该函数有一个参数,即接受的最终结果(the fulfillment value)。如果传入的 onFulfilled 参数类型不是函数,则会在内部被替换为(x) => x ,即原样返回 promise 最终结果的函数
onRejected
当Promise变成拒绝状态(rejection )时,该参数作为回调函数被调用(参考: Function)。该函数有一个参数,,即拒绝的原因(the rejection reason)。
var p = new Promise((resolve, reject) => {
resolve('foo')
})
// 'bar' 不是函数,会在内部被替换为 (x) => x
p.then('bar').then((value) => {
console.log(value) // 'foo'
})
Promise
Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及该异步操作的结果值。
本质上Promise是一个绑定了回调的对象,而不是将回调传进函数内部
- 在本轮 Javascript event loop(事件循环)运行完成 之前,callbacks(回调)是不会被调用的。
- 综上,通过 .then() 形式添加的回调函数总会被调用,即便是在异步操作完成之后才被添加的函数。
- 通过多次调用 .then(),可以添加多个回调函数,它们会按照插入顺序并且独立运行。
- 因此,Promise 最直接的好处就是链式调用。