将已经存在的异步请求callback转换为同步promise

由于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 = 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?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfsxx.html