Promise 对象用于耽误(deferred) 盘算和异步(asynchronous ) 盘算。一个Promise对象代表着一个还未完成,但预期将来会完成的操纵。
先来一个例子 A 熟习下语法
var p = new Promise(function(resolve, reject){
console.log('1');
// 运转后续的 callback 列表,比方:then,when等。不然,不会实行then内里的函数
resolve('go next');
});
// 只斟酌胜利
p.then(function(){
console.log(2, arguments);
return 'next';
}, null).then(function(){
console.log(3, arguments)
}, null);
// 输出
1
2 ['go next']
3 ['next']
最初的想象
function Promise(func){ // 吸收一个函数作为参数
}
Promise.prototype = {
then: function(callback){ // 吸收函数作为参数
return this; // 支撑链式挪用
}
}
视察例 A,resolve是一个函数,而且不是用户传的,一切Promise本身应该有一个resolve要领,而且这个要领要通报给Promise组织器内里的函数作为参数。
function Promise(func){ // 吸收一个函数作为参数
**func(this.resolve);**
}
Promise.prototype = {
**resolve: function(){
}**,
then: function(callback){ // 吸收函数作为参数
return this; // 支撑链式挪用
}
}
Promise是根据递次来实行callback的,而且由resolve触发。
function Promise(func){ // 吸收一个函数作为参数
**this.doneList = []; // callback 列表**
**func(this.resolve.bind(this)); // 顺带绑定this对象**
}
Promise.prototype = {
resolve: function(){
**//实行回调列表
while(true){
if( this.doneList.length === 0 ){
break;
}
this.doneList.shift().apply(this);
}**
},
then: function(callback){ // 吸收函数作为参数
**this.doneList.push(callback); // 加入到回调行列**
return this; // 支撑链式挪用
}
}
好,如今写一个测试用例
var p =new Promise(function(resolve){
console.log('a');
resolve();
}).then(function(){
console.log('b');
});
// 输出
'a'
什么鬼?打印下p
console.log(p);
我们发明本来doneList内里另有一个函数没有运转,再运转下这个函数
p.doneList[0].call(this);
//效果
console.log('b'); // 打印 b
打断点跟踪,发明Promise先实行resolve要领,然后实行then,把函数push到doneList。然则,再也没有实行过doneList内里的函数了。怎么办呢?我们能够给Promise加一个属性(state)来形貌当前状况,分为【未完成】(pending)和【完成】(done)。假如实行then时,状况已经是完成态,那末切换到未完成态,并实行resolve要领。
function Promise(func){ // 吸收一个函数作为参数
**this.state = 'pending'; // 初始化状况**
this.doneList = []; // callback 列表
func(this.resolve.bind(this)); // 顺带绑定this对象
}
Promise.prototype = {
resolve: function(){
//实行回调列表
while(true){
if( this.doneList.length === 0 ){
**this.state = 'done'; // 回调列表为空,转变状况**
break;
}
this.doneList.shift().apply(this);
}
},
then: function(callback){ // 也是吸收函数
this.doneList.push(callback); // 加入到回调行列
if( this.state === 'done'){
this.state = 'pneding';
this.resolve();
}
return this; // 支撑链式挪用
}
}
用和上面相似的例子再次测试
var p =new Promise(function(resolve){
console.log('a');
resolve();
}).then(function(){
console.log('b');
}).then(function(){
console.log('c');
});
效果截图
这下,我们自定义的Promise基本功用完成了最中心的部分了。或许有人会疑问,你这写的什么鬼?下面的代码更简朴,也能完成雷同的功用
function Promise(func){ // 吸收一个函数作为参数
func(this.resolve.bind(this)); // 顺带绑定this对象
}
Promise.prototype = {
resolve: function(){
//什么也不干
},
then: function(callback){ // 也是吸收函数
callback.call(this); // 直接运转
return this; // 支撑链式挪用
}
}
测试用例
var p =new Promise(function(resolve){
console.log('d');
resolve();
}).then(function(){
console.log('e');
}).then(function(){
console.log('f');
});
效果:
然则,文章最前面说过
Promise 对象用于耽误(deferred) 盘算和异步(asynchronous ) 盘算
而且会递次实行回调列表(doneList)。终究代码及测试
function Promise(func){
this.state = 'pending';
this.doneList = [];
func(this.resolve.bind(this));
}
Promise.prototype = {
resolve: function(){
while(true){
if( this.doneList.length === 0 ){
this.state = 'done';
break;
}
this.doneList.shift().apply(this);
}
},
then: function(callback){
this.doneList.push(callback);
if( this.state === 'done'){
this.state = 'pending';
this.resolve();
}
return this;
}
}
var p = new Promise(function(resolve){
window.setTimeout(function(){
console.log('d');
resolve();
}, 1000);
}).then(function(){
console.log('e');
}).then(function(){
console.log('f');
});
console.log('被壅塞了吗?');
输出:
先输出’被壅塞了吗?’,一秒钟后接踵输出 d、e、f 。能够看出,不只没有壅塞背面的代码实行,而且回调也是根据递次实行的。
完毕。
下篇继承完美,比方数据通报以及then中函数返回一个Promise时,怎样处置惩罚。迎接人人有疑问或许发起,一起来交换。