Promise A 规范的一个简单的浏览器端实现

时间:2024-09-12 12:05:14

简单的实现了一个promise 的规范,留着接下来模块使用。感觉还有很多能优化的地方,有时间看看源码,或者其他大神的代码

主要是Then 函数。回调有点绕人。

 !(function(win) {

   function Task(resolver) {
if (!resolver || (typeof resolver).toUpperCase() != 'FUNCTION') {
throw 'task arg is function,and is must';
return;
} if (!(this instanceof Task)) return new Task(resolver); var self = this;
//PENDING,FULFILLED,REJECTED
self.statu = 'PENDING';
self.callbackok = null;
self.callbackreject = null; self.value = null;
self.reason = null; function resolve(data) {
self.statu = 'FULFILLED';
self.value = data || {};
self.callbackok && self.callbackok(self.value);
} function reject(reason) {
self.statu = 'REJECTED';
self.reason = reason || {};
self.callbackreject && self.callbackreject(self.reason);
} resolver(resolve, reject); } Task.all = function(arr) { if (!(arr instanceof Array)) {
throw 'arr must be Task Array';
return;
} return Task(function(resolve, reject) {
var dataarr = {};
var len = arr.length;
for (var i = 0; i < len; i++) {
(function(c) {
console.log(arr[c]);
arr[c].then(function(data) {
dataarr[c] = data;
len--;
if (len == 0) {
var data = new Array(len);
for (var item in dataarr) {
data[item] = dataarr[item];
}
resolve(data);
} }, function(error) {
reject(error);
})
})(i)
}
})
} //创建一个成功状态的Task对象
Task.resolve = function(value) { return new Task(function(resolve) {
resolve(value);
})
} Task.prototype.then = function(onFulfilled, onRejected) { var task = this; return Task(function(resolve, reject) { function callback(value) { var ret = (typeof onFulfilled).toUpperCase() == 'FUNCTION' && onFulfilled(value) || value; if (isThenable(ret)) {
ret.then(function(value) {
resolve(value);
}, function(reason) {
reject(reason);
});
} else {
resolve(ret);
}
} function errorback(reason) {
reason = (typeof onRejected).toUpperCase() == 'FUNCTION' && onRejected(reason) || reason;
reject(reason);
} if (task.statu === 'PENDING') {
task.callbackok = callback;
task.callbackreject = errorback;
} else if (task.statu === 'FULFILLED') {
callback(task.value);
} else if (task.statu === 'REJECTED') {
errorback(task.reason);
} }); } var isThenable = function(obj) {
return obj && typeof obj['then'] == 'function';
} window.Task = Task; })(window)

下面是几种调用

串行

 var task = new Task(function(resolve, reject) {
setTimeout(function() {
resolve('aaaa');
}, 100);
})
var task1 = function() {
return new Task(function(resolve, reject) {
setTimeout(function() {
resolve('bbbb');
}, 100);
})
}
var task2 = function() {
return new Task(function(resolve, reject) {
setTimeout(function() {
resolve('cccc');
}, 100);
})
}
var task3 = function() {
return new Task(function(resolve, reject) {
setTimeout(function() {
reject('dddd');
}, 100);
})
}
task.then(task1).then(task2).then(task3).then(function(data) {
console.log(data)
}, function(error) {
console.log(data)
});

并行

  var task = new Task(function(resolve, reject) {
setTimeout(function() {
resolve('aaaa');
}, 100);
})
var task2 = new Task(function(resolve, reject) {
setTimeout(function() {
resolve('aaaa');
}, 100);
})
var task3 = new Task(function(resolve, reject) {
setTimeout(function() {
resolve('aaaa');
}, 100);
})
var task4 = new Task(function(resolve, reject) {
setTimeout(function() {
resolve('aaaa');
}, 100);
})
var task5 = new Task(function(resolve, reject) {
setTimeout(function() {
resolve('aaaa');
}, 100);
})
//并行
Task.all([task,task2,task3,task4,task5]).then(function(data){ console.log(data)})

创建一个一开始就是 释放状态的 task

Task.resolve('data').then(function(data){
console.log(data);
})