甚么是 AJAX
Asynchronous JavaScript and XML
可以使网页与伺服器进行非同步更新,不需要重新载入网页的技术。
较旧的PHP网站,可能有区域资料变动,就需要重新向伺服器请求,并在伺服器端重新渲染HTML,再由浏览器接收新的HTML造成页面刷新,但是更改的区域又很小,造成不必要的资源浪费。
AJAX则资料皆在客户端处理,不需要刷新页面,即可更新DOM。
同步、非同步概念
JS 是一个非同步语言
执行带有 setTimeout / API Call 不会停下来等待完成后,才进行下一个,因此可能出现错误。
Ex: 取得伺服器资料时太慢,后续程序得不到资料而报错。
同步: 看似所有动作同时进行,实则相反!!!
一个动作执行完,才作下一个动作
非同步: 可以同时进行多个任务
不需要等待上一个动作完成,才作下一个动作
如何解决非同步带来的问题
解法1 CallBack
CallBackHell:
如果太多需要顺序性的程式,就会造成多层巢状,而难以维护。
let funcA = function (callback) { window.setTimeout(() => { console.log('function A') // 如果 callback 是个函式就呼叫它 if (typeof callback === 'function') { callback() } }, 3000) } let funcB = function () { window.setTimeout(() => { console.log('function B') }, 1000) } // 模拟 funcA 资料回传较慢,导致 funcB 会先执行 funcA() funcB() // 为了确保 funcA 内容先作完,才作 funcB 内容 funcA(funcB)
解法2 Promise
支援度差的浏览器可用 es6-promise polyfill
要提供函式有promise功能,使函式return promise物件即可
串接函式顺序 使用 then,resolve才会继续作下去
若不管顺序,只求全部完成使用 Promise.all()
Promise 物件有三种状态
Promise 回传结果只有 完成(resolve) 或 拒绝(reject)
pending 初始状态fulfilled 操作完成rejected 操作失败 // 宣告一个Promise const p1 = new Promise((resolve, reject) => { resolve('OK') // reject(new Error('Error')) }) // 提供 Function 有 promise功能 function promiseFunc(url) { return new Promise((resolve, reject) => { resolve('OK') // reject(new Error('Error')) }) } // 串接函式顺序 使用 then funcA().then(funcB).then(funcC) // Promise.all() Promise.all([funcA(), funcB()]) .then((result) => { console.log(result) }).catch((err) => { console.error(err) })