由于js是单线程执行,为防止阻塞,会有很多异步回调函数callback,嵌套层次多了,可读性就差了很多。随着社区的发展,出现了promise。我们来将一些常见的回调函数做修改,变成promise的链式调用,简洁,清晰明了。
先理解一点点概念。
每个promise都有三个状态。pending、Fulfilled、Rejected。最初为pending,状态一但改变为Fulfilled、Rejected中的一种,即成永远,不再改变。
pending: 等待状态。
Fulfilled: 表示成功完成。
Rejected: 表示被拒绝,失败。
原生的ajax请求 /** * 原生请求 */ 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 风格的请求
/** * 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) }) } jquery中的ajax请求这里只使用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) } }) }) } node风格的callback请求 nodeGet(param, function (err, data) { })TO:
function nodeGetAysnc(param) { return new Promise((resolve, reject) => { nodeGet(param, function (err, data) { if (err !== null) return reject(err) resolve(data) }) }) } DOM load事件 或者其他一次性事件 function load() { console.log('onload - end') } window.onload = loadTO 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?