ES6 原生供应了 Promise 对象,大大简化了 callback 的代码保护难度。运用promise对象以后能够运用一种链式挪用的体式格局来构造代码;让代码越发的直观。
假如想在老浏览器中运用 Promise,须要运用第三方库。现实完成阔别并不庞杂,仅须要十几行代码,就可以完成相似的效果(现实照样有点区分的)。
// 简朴的完成 Promise 的函数
// 原文地点:http://www.miaoqiyuan.cn/p/promise
var PromiseDemo = function(fun, _status_code){
this._status_code = _status_code || 'status';
//实行
this.run = function(){
this._result = fun.call(this, fun);
//假如实行函数会 同步 返回效果,则挪用callback。
if( !! this._result ){
return this.callback();
};
};
//回调函数,假如不是马上返回效果,须要手动挪用
this.callback = function(_result){
//异部挪用时,传入实行效果
if( !!_result ){
this._result = _result;
}
//如过状况不是 object
this._result = this._result || {};
//假如没有指定 【返回状况】 值,假如没有,则运用 status
this._status = this._result[this._status_code] || 'fail';
/*
假如 【返回状况】 已定义了 回调函数,挪用本状况回调函数
假如 【返回状况】 没有定义,则挪用 _default 函数
假如 【返回状况】 没有定义,而且没有挪用 _default 函数,抛出非常
*/
this._callback = this[this._status] || this._default || function(){ throw new Error("Undefined " + this._status); };
return this._callback.call(this);
};
//then推断
this.then = function(_status, callback){
if( typeof _status == "function" ){
//没有指定状况
callback = _status;
if( !('success' in this) ){
//没有 success,则将 callback 设置为 success 状况的回调函数
_status = 'success';
}else if( !('fail' in this) ){
//没有 fail,则将 callback 设置为 fail 状况的回调函数
_status = 'fail';
}else{
// 假如 success 和 fail 已设置,不管挪用多少次,都是 默许状况 的回调函数
_status = '_default';
};
};
//设置 【返回状况】 的回调函数
this[_status] = callback;
//链式操纵
return this;
};
//链式操纵
return this;
}
就这么几行代码,就完成了简朴的 Promise。为了轻易测试,写成函数
var PromiseTest = function(fun, _status_code, _default){
if( typeof _status_code == "function" ){
_default = _status_code;
_status_code = undefined;
}
var pTest = new PromiseDemo(fun, _status_code);
pTest.then(function(){
console.log("Success!");
console.log(this._result);
});
pTest.then(function(){
console.log("Fail!");
console.log(this._result);
});
if( typeof _default == "function"){
pTest.then(_default);
};
return pTest;
}
下面的代码用于测试效果:
返回胜利状况
PromiseTest(function(){
return { status: 'success'};
}).run();
/*
Success!
Object {status: "success"}
*/
返回失利状况
PromiseTest(function(){
return { status: 'fail'};
}).run();
/*
Fail!
Object {status: "fail"}
*/
返回其他状况,没有定义,抛出非常
PromiseTest(function(){
return { status: 'other'};
}).run();
/*
Uncaught Error: Undefined other(…)
*/
修正 【返回状况】 参数,返回胜利状况
PromiseTest(function(){
return { status: 'other', code : 'success'};
}, "code").run();
/*
Success!
Object {status: "other", code: "success"}
*/
增添默许值函数,一切未定义的状况,都是用此回调函数
PromiseTest(function(){
return { status: 'other'};
}, function(){
console.log("Other");
}).run();
/*
Other
*/
自定义状况值,返回 nicai 状况
PromiseTest(function(){
return { status: 'nicai'};
}).then('wocai', function(){
console.log("Wocai");
}).then('nicai', function(){
console.log("Nicai");
}).run();
/*
Nicai
*/
同步挪用有返回值
PromiseTest(function(){
return { status: 'nicai', value : "abc"};
}).then('nicai', function(){
console.log("Nicai");
return this._result.value;
}).run() == 'abc';
/*
Nicai
true
*/
异部挪用测试:setTimeout
PromiseTest(function(){
setTimeout(
(function(){
this.callback({
status : 'success'
});
}).bind(this), //必需bind,不然函数内部的 this == window
1000);
}).run();
/*
Success!
Object {status: "success"}
*/
异部挪用测试:Ajax
PromiseTest(function(){
$.ajax({
type : "POST",
url : "/services/PinYin",
data : {input:'测试'},
success : (function(result){
this.callback({
status : 'success',
result : result
});
}).bind(this), //经由过程 bind 转变 this 的指向
error : (function(){
this.callback();
}).bind(this)
});
}).run();
//胜利
/*
Success!
Object {status: "success", result: "Ceshi"}
*/
//失利
/*
Fail!
Object {}
*/
异部挪用测试:假如须要用 this 接见 jQuery 的 ajax 对象
PromiseTest(function(){
var me = this; //在本函数内,用能够 me 指向 this(PromiseDemo的实例);
$.ajax({
type : "POST",
url : "/services/PinYin",
data : {input:'测试'},
success : (function(result){
me.callback({
status : 'success',
result : result
});
}),
error : (function(){
me.callback();
})
});
}).run();