本节书摘来自异步社区《AngularJS高级程序设计》一书中的第5章,第5.9节,作者:【美】Adam Freeman(弗里曼)著,更多章节内容可以访问云栖社区“异步社区”公众号查看
5.9 使用承诺
承诺是一种表述方式,它表明某项工作会以异步方式执行并在未来某个点被完成。最常遇到的方式是产生Ajax请求,当请求被完成时,浏览器会暗地里发出HTTP请求通知你的应用程序。在清单5-42中,我创建了产生Ajax请求的袖珍AngularJS应用程序。
注意:
该示例依赖于我在章节伊始创建的todo.json文件。
清单5-42 在文件jsdemo.html中创建袖珍AngularJS应用程序
我在该清单中所使用的AngularJS特性是在第2章中所熟知的。我创建了AngularJS模块并给了它控制器demoCtrl。控制器使用$scope对象为视图提供数据,该视图有使用数据绑定和ng-repeat指令的表格。你可以在图5-3中看到浏览器是如何显示该示例的。
JavaScript及异步编程
如果你是从像C#或Java语言来到JavaScript的,你可能会惊讶于缺失控制异步代码执行的关键字,诸如lock或synchronized之类的。JavaScript不支持这种流控制或提供对设置优先级的支持。这致使了更简单的开发者体验,即使它很容易不小心产生副作用。我将在第20章中讲AngularJS对创建自定义承诺的支持时回到这一话题。
模块、控制器和视图就是全部我向你展示承诺如何工作所需设置的设施了。清单的重要部分在这:
$http服务(我在第20章讲它)用于产生Ajax请求,然后get方法取到你想从服务器获取的文件的URL。(仅通过指定文件名,我就能告诉浏览器我想要的文件在当前所显示的HTML文档旁边的哪里。)
Ajax请求是被异步执行的,当请求发出时,浏览器继续运行我的简单应用程序。$http.get方法返回承诺对象,我可以用它接收关于Ajax请求的通知。在本例中,我使用success方法注册了将在请求完成后被调用的回调函数。该回调函数接收从服务器拿到的数据,我使用它把属性赋值给$scope,接着依次给出ng-repeat指令的内容填充to-do项的表格。Success方法是承诺对象所定义的三个中的一个,如表5-7所示。
表5-7 承诺对象定义的方法
三个方法都用函数作为参数,并根据承诺的结果而调用。回调函数success会被传入从服务器拿到的数据,而回调函数error接收遭遇到问题的详情。
提示:
另一个方式是考虑承诺所定义的方法是类似于事件的。在这种方式中在用户单击按钮并触发事件时回调函数会被调用,承诺将在工作被完成时调用回调函数。
三个承诺方法都返回承诺对象,让异步任务可以按顺序链接在一起。清单5-43包含简单示例。
清单5-43 在文件jsdemo.html中链接承诺
这里我使用了then方法两次,第一次是处理调用$http.get方法的响应,并再次注册稍后将被调用的函数。这种类型的代码很难读,所以我会使用依序高亮显示。第一,我调用get方法创建Ajax请求:
我使用then方法提供函数,它在Ajax请求完成时将被调用。第一个在请求成功时调用,而第二个在请求失败时:
承诺保证那些函数中的一个将被调用,但不是直到Ajax请求被完成或失败才调用。我使用then方法再次添加了额外的函数:
这一次我仅仅为then方法传入一个函数,意味着如果有问题我也不想要通知。这最后的函数不顾之前被调用过的函数,向数据模型添加了一项。你可以在图5-4中看到Ajax请求成功的效果。
提示:
如果暂时链接的不太好也不用担心。当你开始在你自己的项目中使用承诺时你将很快有主意,你会在第20章中(在我讲AngularJS对Ajax的支持时)以及第21章中(在我讲RESTful的Web服务时)看到更多的承诺示例。