在本 系列 的之前几个部分中,您了解了 CoffeeScript 的优势、设置了开发环境、尝试了许多特性,还使用 CoffeeScript 为一个实际应用程序编写了客户端代码。在本系列的最后一篇文章中,我们将编写服务器端 CoffeeScript 代码。
CoffeeScript 是构建在 ">JavaScript 基础之上的一种全新编程语言,提供了能够吸引 Python 或 Ruby 爱好者的整洁的语法。此外还提供了受 Haskell 和 Lisp 等语言启发得出的许多函数式编程特性。
在本 系列文章 的 第 1 部分 中,我们了解了使用 CoffeeScript 的优势。此外还设置了开发环境,运行了脚本。在 第 2 部分 中,我们在尝试解决数学问题的过程中尝试了许多 CoffeeScript 特性,探索了 CoffeeScript 编程语言。在 第 3 部分 中,为一个 Web 应用程序编写了客户端代码。
在最后的这篇文章中,您将编写服务器端组件,并完成应用程序 — 所有一切都是使用 CoffeeScript 完成的。
调用所有 Web 服务
第 3 部分 中的 Web 应用程序使用一个关键字执行了 Google 和 Twitter 搜索。对于应用程序的客户端,您模拟了来自服务器的结果。为了实际实现此类功能,您需要应用程序的服务器端调用 Google 和 Twitter 提供的 Web 服务。两家公司均提供了非常简单的搜索服务。您只需对搜索服务发出 HTTP GET 请求即可。清单 1 展示了发出 HTTP GET 请求的一般函数。
清单 1. 获取 Web 资源
http = require "http" fetch
Page = (host, port, path, callback) -> options = host: host port: port path: path req = http.get options, (res) -> contents = "" res.on 'data', (chunk) -> contents += "#{chunk}" res.on 'end', () -> callback(contents) req.on "error", (e) -> console.log "Erorr: {e.message}"
require 语句是脚本的第一条语句,在本系列的 第 1 部分 中已经对此进行了简单的介绍。这是一种 Node.js 模块导入语法,或者至少应该说是这种语法的 CoffeeScript 版本。“原生” 版本应该是 var http = require("http");。在这篇文章中,您将使用多个 Node.js 核心模块。(这些模块的工作原理不在本文讨论范围之内。)如果您安装了 Node.js,那么就应该能使用本文中使用的所有模块(请参见 第 1 部分)。对于 清单 1 中的示例,您使用的是 http 模块,它为发出和接收 HTTP 请求提供了一些非常有用的类和函数。
清单 1 随后定义了一个 fetchPage 函数,可以接受以下四个参数:
资源的 host 名称。 资源的 port。 资源的 path。 一个 callback 函数。
Node.js 中任何类型的 I/O 函数在本质上都是异步的,因此在完成时需要通过一个 callback 函数进行调用。fetchPage 函数接受一个 callback 函数作为第四个参数。随后使用前三个参数,通过 http 模块的 get 函数发出一条 HTTP GET 请求。
fetchPage 函数也获取一个 callback 函数,将有一个 ClientResponse 实例传递给后一个函数。ClientResponse 是 http 模块中定义的一个对象,它实现了 ReadableStream 接口(Node.js 中的核心接口)。这是一个异步接口,接受两个事件:data 和 end。其惟一的函数用于为这些事件注册回调。在从您发出 HTTP GET 请求的资源接收到数据时,将发生数据事件。
资源将一次性返回所有数据,但更常见的做法是分块发送数据。接收到各块时,数据事件将被触发,回调将被调用。您创建了一个名为 contents 的变量;每次接收到另一个块时,都会将其附加到 contents。接收了所有数据之后,即触发 end 事件。现在,您获得了全部数据,因此可以将 contents 传递给传入 fetchPage 函数的 callback 函数。定义了这个多用途函数之后,下面我们将为 Google 和 Twitter 搜索 API 创建一些专用函数,如 清单 2 所示。
清单 2. Google 与 Twitter 搜索函数
googleSearch = (keyword, callback) -> host = "ajax.googleapis.com" path = "/ajax/services/search/web?v=1.0&q=#{encodeURI(keyword)}" fetchPage host, 80, path, callbacktwitterSearch = (keyword, callback) -> host = "search.twitter.com" path = "/search.json?q=#{encodeURI(keyword)}" fetchPage host, 80, path, callback
清单 2 中定义了两个函数:
googleSearch,用于获取一个 keyword 和一个 callback 函数。它将固定主机,并使用 CoffeeScript 的字符串插值创建路径,随后使用 fetchPage。 twitterSearch,该函数与 googleSearch 极为相似,但使用了不同的主机和路径值。
对于两个路径值,您都要使用字符串插值和 JavaScript 提供的便捷的 encodeURI 函数来处理任何空格或其他特殊字符。现在您已经拥有了这些搜索函数,下面即可为合并搜索场景创建特殊函数。