解决异步代码的多层嵌套问题 ; 存在兼容性问题,靠编译解决
1.basic usage
let p = new Promise(function (resolve, reject){
$.ajax({
url: '/data',
dataType: 'json',
success(arr){
resolve(arr);
},
error(err){
reject(err);
}
});
});
p.then(arr=>{alert('成功了'+arr);}, err=>{alert('失败了');});
Promise.all([
$.ajax({url: 'data/1.txt', dataType: 'json'}),
$.ajax({url: 'data/2.txt', dataType: 'json'}),
]).then(arr=>{
alert('成功');
console.log(arr);
}, err=>{
alert('失败了');
});
//promise creator
function ajaxPromise(url){
return new Promise(function (resolve,reject) {
//do ajax operations
})
}
2.implement my Promise
/*
1.创建一个 Promise Class,接收函数 fn(resolve,reject){} 作为参数
2.在fn中进行异步操作,成功返回则触发 resolve 函数,失败触发 reject 函数
3.promise instance 状态 state 变化 : pending --> resolved || rejected
4.通过 then() 将成功和失败回调函数都保存起来
5.异步返回后,根据返回的成败结果调用所有对应的成败回调函数
*/
class Promise {
constructor(ajaxFn) {
this.callbackQueue = [
// format
// {
// fn1, for successful callback
// fn2 for failed callback
// }
];
this.state = "pending"; //default state
this._success_result = null;
this._failure_result = null;
const _this = this;
//call async operation
ajaxFn(function (...args) {
_this.state = "success";
_this.callbackQueue.forEach(function(callbackObj){
callbackObj.fn1(...args);
});
_this._success_result = args;
}, function (...args) {
_this.state = "failure";
_this.callbackQueue.forEach(function(callbackObj){
callbackObj.fn2(...args);
});
_this._failure_result = args;
});
}
//Promise instance call then(),state maybe changed
then(fn1, fn2) {
const state = this.state;
if(state === "success"){
fn1(this.success_result);
}else if(state === "failure"){
fn2(this.failure_result);
}else{
this.callbackQueue.push({
fn1,fn2
});
}
}
static all(arr){
const results = [];
return new Promise(function(resolve,reject){
//需按数组中的promise的顺序返回,这种控制异步回调的方式较常用
let i=0;
function next(){
arr[i].then(function(res){
results.push(res);
i++;
if(i === arr.length){
resolve(results);
}else{
next();
}
},reject);
}
next();
});
}
static race(arr){
//......
}
}