因爲js是單線程執行,爲防止阻塞,會有不少異步回調函數callback,嵌套層次多了,可讀性就差了不少。隨着社區的發展,出現了promise。咱們來將一些常見的回調函數作修改,變成promise的鏈式調用,簡潔,清晰明瞭。node
先理解一點點概念。jquery
每一個promise都有三個狀態。pending、Fulfilled、Rejected。最初爲pending,狀態一但改變爲Fulfilled、Rejected中的一種,即成永遠,再也不改變。es6
pending: 等待狀態。ajax
Fulfilled: 表示成功完成。api
Rejected: 表示被拒絕,失敗。promise
/** * 原生請求 */ function nativeRequest(url) { var xhr = new XMLHttpRequest() // 這裏我建議的書寫順序是: onreadystatechange -> open -> send // 這樣,onreadystatechange 能夠獲取 readyState 的狀態 1 2 3 4 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { // 請求已完成,且響應已就緒 if (xhr.status === 200) { // TODO: 處理返回正常的數據 xhr.responseText } else { // TODO: 處理返回非正常的數據 } } } xhr.open('GET', url, true) xhr.send(null) }
promise 風格的請求dom
/** * promisify request * 返回promise對象 */ function promiseRequest(url) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest() xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(xhr.responseText) } else { reject(xhr.responseText) } } } xhr.open('GET', xhr, true) xhr.send(null) }).catch(err => { console.log(err) }) }
這裏只使用ajax請求中的get請求,使用常見的幾個參數。異步
/** * ajax get請求 */ function ajaxResponse(url) { $.ajax({ url: url, type: 'GET', success: res => { console.log(res) }, error: err => { console.log(err) } }) }
轉換爲promise風格函數
/** * promise風格的ajax get請求 * 返回promise對象 * 這裏同時用到了es6中的解構賦值默認值和函數參數默認值 */ function promiseAjaxResponse(url, { type = 'GET', } = {}) { return new Promise((resolve, reject) => { $.ajax({ url, type, success: res => { resolve(res) }, error: err => { reject(err) } }) }) }
nodeGet(param, function (err, data) { })
TO:url
function nodeGetAysnc(param) { return new Promise((resolve, reject) => { nodeGet(param, function (err, data) { if (err !== null) return reject(err) resolve(data) }) }) }
function load() { console.log('onload - end') } window.onload = load
TO promise
function promiseLoad() { return new Promise(function (resolve, reject) { window.onload = resolve }) } promiseLoad().then(load)
參考
1.How do I convert an existing callback API to promises?
2.How do I promisify native XHR?