深入理解promise/ajax
Promise 对象特点
- 对象的状态不受外界影响。 Promise对象代表一个异步操作, 有三种状态: pending( 进行中)、 fulfilled( 已成功) 和rejected( 已失败)。 只有异步操作的结果, 可以决定当前是哪一种状态, 任何其他操作都无法改变这个状态。
一旦状态改变, 就不会再变, 任何时候都可以得到这个结果。 Promise对象的状态改变, 只有两种可能: 从pending变为fulfilled和从pending变为rejected。 只要这两种情况发生, 状态就凝固了, 不会再变了, 会一直保持这个结果, 这时就称为 resolved( 已定型)。 如果改变已经发生了, 你再对Promise对象添加回调函数, 也会立即得到这个结果。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。 Promise对象的状态改变, 只有两种可能: 从pending变为fulfilled和从pending变为rejected。 只要这两种情况发生, 状态就凝固了, 不会再变了, 会一直保持这个结果, 这时就称为 resolved( 已定型)。 如果改变已经发生了, 你再对Promise对象添加回调函数, 也会立即得到这个结果。
Promise缺点
- 无法取消promise, 一旦新建它会立即执行, 无法中途取消。
- 如果不设置回调函数, promise内部抛出的错误, 不会反应到外部
- 当处于pending 状态时, 无法得知目前进展到那一阶段。
原生ajax
const ajax = function (params) {
if (!params.url) return
const promise = new Promise((resolve, reject) => {
const handler = function () {
if (this.readyState !== 4) return
if (this.status == 200) {
resolve(this.responseText)
} else {
reject(this.statusText)
}
}
const xhr = new XMLHttpRequest()
if (params.method.toLowerCase() == 'get') {
xhr.open('get', url + '?' + formatParams(params.data));
xhr.send()
} else {
xhr.open('post', url);
xhr.send(JSON.stringify(params.data));
}
xhr.onreadystatechange = handler xhr.responseType = 'json'
xhr.setRequestHeader('Accept', 'application/json');
})
return promise
function formatParams(obj) {
if (!data) return
var arr = []
for (let i in obj) {
arr.push(`${encodeURIComponent(i)}=${encodeURIComponent(obj[i])}`)
}
return arr.join('&')
}
}
asyncpool Es6 实现
function asyncPool(poolLimit, array, iteratorFn) {
let i = 0;
const ret = []
const executing = [];
const enqueue = function () {
if (i === array.length) {
return Promise.resolve();
}
const item = array[i++];
const p = Promise.resolve().then(iteratorFn(item, array));
ret.push(p)
let r = Promise.resolve();
if (poolLimit <= array.length) {
const e = p.then(() => {
return executing.splice(executing.indexOf(e), 1)
})
executing.push(e)
if (executing.length >= poolLimit) {
r = Promise.race(executing)
}
}
return r.then(() => enqueue())
}
return enqueue().then(() => Promise.all(ret))
}