思想: 在执行本Promise的方法(每个方法都对应着下一个Promise)的时候,将下一个Promise的方法(全部方法)加入到任务队列,其中,最后的Promise的方法为空。
两个数组:成功时要执行的方法数组_doneCallbacks,失败时要执行的方法数组_failCallbacks。
注:根据本Promise方法的执行情况,决定下一个Promise执行哪个数组中的方法(_doneCallbacks还是_failCallbacks)。
delete window.Promise;
var Status = {
PENDING: "pending",
FULLFILLED: "resolved",
REJECTED: 'rejected'
};
function Promise(func) {
if(!(this instanceof Promise)) {
throw new TypeError("TypeError: undefined is not a promise");
}
if(typeof func != "function") {
throw new TypeError("TypeError: Promise's argument is not a function");
}
this._status = "pending";
this._value;
this._doneCallbacks = [];
this._failCallbacks = [];
var promise = this;
try {
func(function(data) {
resolve(promise, data);
}, function(reason) {
reject(promise, reason);
});
} catch(e) {
reject(promise, e);
}
}
function resolve(promise, data) {
if(promise._status !== Status.PENDING) {
return;
}
promise._status = Status.FULLFILLED;
promise._value = data;
run(promise);
}
function reject(promise, reason) {
if(promise._status !== Status.PENDING) {
return;
}
promise._status = Status.REJECTED;
promise._value = reason;
run(promise);
}
function run(promise) {
if(promise._status === Status.PENDING) {
return;
}
var value = promise._value;
var callbacks = promise._status === Status.FULLFILLED ? promise._doneCallbacks : promise._failCallbacks;
//保证
setTimeout(function() {
for(var i = 0; i < callbacks.length; i++) {
callbacks[i](value);
}
}, 0);
promise._doneCallbacks = [];
promise._failCallbacks = [];
}
function empty() {}
Promise.prototype.then = function(onResolve, onReject) {
var promise = new Promise(empty);
this._doneCallbacks.push(makeCallback(promise, onResolve, "resolve"));
this._failCallbacks.push(makeCallback(promise, onReject, "reject"));
run(this);
return promise;
}
Promise.prototype.catch = function(onReject) {
return this.then(null, onReject);
}
function makeCallback(promise, callback, action) {
return function(value) {
if(typeof callback === "function") {
var x;
try {
x = callback(value);
} catch(e) {
reject(promise, e);
return;
}
if(x === promise) {
var reason = new TypeError("TypeError: The return value could not be same with the promise");
reject(promise, reason);
} else if(x instanceof Promise) {
x.then(function(data) {
resolve(promise, data);
}, function(reason) {
reject(promise, reason);
});
} else if(typeof x === "object" || typeof x === "function") {
// var then;
// try{
// then=x.then;
// }catch (e){
// reject(promise,e);
// return;
// }
// if(typeof then==="function"){
// then.call(x,)
// }
} else {
resolve(promise, x);
}
} else {
action === "resolve" ? resolve(promise, value) : reject(promise, value);
}
}
}
Promise.all = function(iterable) {
if(!iterable || !iterable.hasOwnProperty("length")) {
throw new TypeError('TypeError: Parameter "iterable" must be a iterable object');
}
var promise = new Promise(empty);
for(var i = 0; i < iterable.length; i++) {
item = iterable[i];
if(!(item instanceof Promise)) {
//转化
}
item.then(makeCallBack("resolve"), makeCallBack("reject"));
}
var args = [];
var count = 0;
function makeCallBack(action) {
return function(val) {
if(action === "reject") {
reject(promise, val);
return;
}
args.push(val);
if(++count === iterable.length) {
resolve(promise, args);
}
};
}
return promise;
}
Promise.race = function(iterable) {
if(!iterable || !iterable.hasOwnProperty("length")) {
throw new TypeError('TypeError: Parameter "iterable" must be a iterable object');
}
var promise = new Promise(empty);
for(var i = 0; i < iterable.length; i++) {
item = iterable[i];
if(!(item instanceof Promise)) {
}
item.then(function(data) {
resolve(promise, data);
}, function(reason) {
reject(promise, reason);
});
}
return promise;
}
Promise.resolve = function(obj) {
if(typeof obj !== "object" || typeof obj.then !== "function") {
return new Promise(function(resolve, reject) {
resolve(obj);
});
}
if(obj instanceof Promise) {
return obj;
}
if(typeof obj.then === "function") {
return new Promise(obj.then);
}
}
阿里前端关于Promise的一道在线编程题:
//实现 mergePromise 函数,把传进去的数组顺序先后执行,并且把返回的数据先后放到数组(data)中。
//思路:先生成一个fulfilled状态的Promise(假设为W),然后将W后跟的一连串then(f)中的f函数
//返回值设置为Promise即可
//在(A)promise.then(f)中遇到f的返回值为Promise对象(B),
//则A从返回值为Promise对象的then处中断then链,转而从头开始执行
//B所在的then链,当B的then链执行结束(准确说不是结束,后面还有一个空的),
//重新从断点处唤醒A的then链
const timeout = ms => new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});
const ajax1 = () => timeout(2000).then(() => {
console.log('1');
return 1;
});
const ajax2 = () => timeout(1000).then(() => {
console.log('2');
return 2;
});
const ajax3 = () => timeout(2000).then(() => {
console.log('3');
return 3;
});
const mergePromise = ajaxArray => {
return new Promise(function(resolve) {
let arr = [];
let cur = Promise.resolve().then(() => {
return ajaxArray[0]();
});
for(let i = 1; i < ajaxArray.length; i++) {
cur = cur.then((data) => {
arr.push(data);
return ajaxArray[i]();
});
}
cur.then((data) => {
arr.push(data);
resolve(arr);
});
// ajaxArray[0]().then(function(data) {
// arr.push(data);
// ajaxArray[1]().then(function(data) {
// arr.push(data);
// ajaxArray[2]().then(function(data) {
// arr.push(data);
// resolve(arr)
// });
// });
// });
});
};
mergePromise([ajax1, ajax2, ajax3]).then(data => {
console.log('done');
console.log(data); // data 为 [1, 2, 3]
});
// 分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]