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