Promise在javascript中得到了越来越广泛的应用,尤其是server side的javascript,比如Node.js编程里。尽管Promise也有其自身的问题,但是它在解决多层嵌套callback,以及其它一些问题时还是有它独特的优点的。
Promise的常用场景基本都是在server side, 但其实在client side, 它也有用武之地,只是目前较为少见而已。
jQuery作为一个优秀的client side的javascript库, 已经全面支持Promise, 只不过我们通常用到的API, 例如$.ajax等,已经把Promise的功能包装在内,开发者感觉不到而已。但是在某些场景下,需要显示的使用Promise来达到目的。
比如这个简单例子:调用外部REST API取得一个任务列表,然后在页面上生成select。
如果想把取得任务列表作为单独一个function,而且不想把生成select的code放到取任务列表的ajax调用的callback里面去, 通常我们会在ajax调用里面使用"async: false",这样一来,取任务列表就变成了同步的。
function generateTaskSelect(value) {
var combine = $('<div></div>');
var label = $('<span></span>').text('Task List');
var cr = $('<div></div>');
var select = $('<select></select>');
var names = getTaskNames();
names.sort();
for (var i=0;i<=names.length-1;i++) {
select.append(generateOption(names[i]));
}
if ((value) && (names.indexOf(value) !== -1)) {
select.val(value);
} else {
if (names.length > 0) {
select.val(names[0]);
}
}
combine.append(label).append(cr).append(select);
return combine;
}
function getTaskNames() {
var names = new Array();
$.ajax({
url: $('#serviceUrl').val() + '/tasks',
type: "GET",
async: false
}).done(function(tasks) {
tasks.forEach(function(task){
names.push(task.name);
});
}).fail(function(err) {
console.error(err);
});
return names;
}
function generateOption(option) {
if (option) {
return $('<option>' + option + '</option>');
} else {
return $('<option></option>');
}
}
function generateTaskSelect(value) {
var combine = $('<div></div>');
var label = $('<span></span>').text('Task List');
var cr = $('<div></div>');
var select = $('<select></select>');
$.when(
getTaskNames()
).done(function(taskNames){
var names = taskNames;
names.sort();
for (var i=0;i<=names.length-1;i++) {
select.append(generateOption(names[i]));
}
if ((value) && (names.indexOf(value) !== -1)) {
select.val(value);
} else {
if (names.length > 0) {
select.val(names[0]);
}
}
combine.append(label).append(cr).append(select);
}).fail(function(err){
console(err);
});
return combine;
}
function getTaskNames() {
var dtd = $.Deferred();
$.ajax({
url: $('#serviceUrl').val() + '/tasks',
type: "GET"
}).done(function(tasks) {
var names = new Array();
tasks.forEach(function(task){
names.push(task.name);
});
dtd.resolve(names);
}).fail(function(err) {
console.error(err);
dtd.reject(err);
});
return dtd;
}
function generateOption(option) {
if (option) {
return $('<option>' + option + '</option>');
} else {
return $('<option></option>');
}
}
其中关键的Promise使用有两点:
1. $.Deferred(): 这就是jQuery中的Promise对象, 注意它的 resolve() 和 reject()状态转换方法的使用。
2. $.when(): 通过它形成了Promise调用链, 对嵌套callback解耦。
原文地址:http://blog.csdn.net/alexgreenbar/article/details/42494855