About
RSS

Bit Focus


填坑 - Stekinscript 异步表达式

    深夜潜入一家竞争对手公司, 可惜只偷到了最后一页源代码的打印稿, 回来一看
            });
        });
    });
})();
    这是何等的引人泪下的故事.

    这不再是 Javascript 刚刚发明的那个年代, 程序员一边用 Java 一边咒骂着花括号嵌套又嵌套何时是个头; 有经验的程序员告诫那些乳臭未干的学生军函数一定要写短, 逻辑多拆分. 有时会想着, 有什么语言会强制规定单一函数的复杂度, 以让每个函数几乎都能限制在一二十行之内呢? 结果现在这个梦想成真了, 对于 Javascript 程序员而言, 这是不得不做的纯天然方式.
    比如 Javascript 中采用异步的方式来解决 IO 效率低的问题, 下面是一段用来读取 "/etc/passwd" 内容的 node 代码
fs: require('fs');
fs.readFile('/etc/passwd', function(err, data) {
    if (err) {
        return console.error(err);
    }
    console.log(data.toString());
});
    看着全局空间里洋洋洒洒一大串内容, 其实只有两句话, 第一句引入库, 第二句读文件; 而对文件的处理则单独放在另一个函数了. 多好的强制函数拆分机制, 现在再也不担心老大说函数写太长了. 不过稍微复杂一些的需求就开始疼了, 比如实现从 "/etc/passwd" 中读取前 32 个字节, node 代码为
fs: require('fs');
fs.open('/etc/passwd', 'r', function(err, fd) {
    if (err) {
        return console.error(err);
    }
    fs.read(fd, new Buffer(32), 0, 32, 0, function(err, bytes, buffer) {
        if (err) {
            fs.close(fd);
            return console.error(err);
        }
        console.log(buffer.toString());
        fs.close(fd);
    });
});
    望着这回调套回调向着行中陷落下去的代码, 感觉就是挖一个大坑. 各位 Javascript 程序员肯定不希望自己的宝贝女儿在幼儿园被问到「你父亲是做什么的」的时候回答「我也不太清楚但是看起来像是用在电脑里画楼梯的」吧.

    所以我想, 得从坑里爬出来.
    考虑到「相当一部分的异步调用貌似都是这个语句块的最后一个语句」继而有了「那为什么不在代码里面用标记让一个语句块里的语句实际上是两部分或更多部分, 第一个部分对应于当前语句块, 而后面的每个部分各是一个异步回调的函数体」这样的想法.
    有了这个想法后就打起了草稿, 比如上面的前一个例子, 要是写成这样
fs: require('fs')
fs.readFile('/etc/passwd', %(err, data))
if err
    return console.error(err)
console.log(data.toString())
    感觉如何? %(err, data) 这就是一个标记, 称之为异步占位符, 它可以作为函数调用的实参出现 (不能单独写在语句中或者进行算术运算). 异步占位符表示一个匿名函数 (参数列表同异步占位符中标识符列表), 如果一个语句中的某个函数调用中有实参为异步占位符, 那么同一个语句块内, 这个函数调用之后的部分都会被移进异步占位符所表示的匿名函数的函数体中去.
    也就是说, 上述代码中, 该匿名函数中的代码会包括
if err
    return console.error(err)
console.log(data.toString())

Permanent Link: ?p=504 Load full text

Post tags:

 NodeJS
 Asynchronous Expression
 Stekin

NodeJS liteview Postgres Stekinscript 搭建留言板 [完]

上篇

前期准备

安装软件与库

    需要安装
  • Postgres (建议 9 或以上版本)
  • libpq-dev
    npm 安装 Postgres 库
npm install pg

配置数据库与表

    参考这篇文章前半部分配置 Postgres 数据库.
    如果已经为 PG 用户 psuser 授权使用 mydb 这个数据库, 现在进入数据库
psql -Upsuser -dmydb -W
Password for user psuser:
建立数据表用于存放留言
mydb=> CREATE TABLE message (
mydb(>   id SERIAL,
mydb(>   content TEXT,
mydb(>   post_time TIMESTAMP DEFAULT NOW(),
mydb(>   PRIMARY KEY(id)
mydb(> );
NOTICE:  CREATE TABLE will create implicit sequence "message_id_seq" for serial column "message.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "message_pkey" for table "message"
CREATE TABLE

显示留言信息

更新页面模板

    之前的页面模板实在显得太单薄, 下面修改一下准备放入留言数据
<html>
<head><title>Guestbook</title></head>
<body>
#{foreach(#messages)}
<div>
    <p style='font-size: 0.6em'>#{[post_time]}</p>
    <p style='margin-left: 20px'>#{[content]}</p>
</div>
#{end}
    liteview 文档如是说
  • #{foreach(#XXX)} 即在 XXX 对象上作循环
  • #{[YYY]} 即每次循环的循环变量的 YYY 属性
    因此上面的页面模板需要传入留言对象列表, 每个留言对象有属性 post_time, content. 这命名与数据库表是一致的.
    然后改一下 index.stkn, 放假数据进去先看看效果
view: require('liteview').create()

exports.get: (request, response):
    response.writeHead(200, { 'Content-Type':: 'text/html' })
    response.end(view.render('index.html', {messages: [
        {
            post_time: '1970-01-01 00:00:00',
            content: 'Nostalgia',
        },
        {
            post_time: '1970-01-01 00:00:00',
            content: 'Eternal Rite',
        },
        {
            post_time: '1970-01-01 00:00:00',
            content: 'Shinto Shrine',
        },
    ]}))
    刷下页面, 这些东西就出现了.

从数据库加载内容

    巧妇难为无米之炊, 现在首先要做的是向数据库插入一些数据. 还是更刚才建表一样, 进入 psql, 使用下面的语句插入一些水帖

Permanent Link: ?p=500 Load full text

Post tags:

 Postgres
 Stekin
 Tutorial
 Web Server
 NodeJS

NodeJS liteview Postgres Stekinscript 搭建留言板 [零]

前期准备

配置软件与库

    需要安装
  • nodejs 0.8 或以上版本 (之后编译 Postgres 模块需要高版本)
  • npm
  • 下载编译 Stekinscript (非必需) $ git clone git://github.com/neuront/stekinscript.git
    Ubuntu 用户安装 nodejs 0.8 版本请加入下面的源
add-apt-repository ppa:chris-lea/node.js
    创建一个工作目录, 通过 npm 安装要用到的模块
npm install liteview
npm install validator

Stekinscript 快速入门 (非必需)

    请参见 https://github.com/neuront/stekinscript/wiki/Language-Specification.
    对 Stekinscript 没有兴趣的同学可以无视这一步, 在每节之后生成的 Javascript 代码会奉上, 对于 Stekinscript 代码, 可以认为它是更易阅读的 JS.

开工

上手

    创建如下内容的 main.stkn 文件, 先启动一个简单的服务器
http: require('http')

port: 8888

http.createServer((request, response):
    response.writeHead(200, { 'Content-Type':: 'text/html' })
    response.end('<html><body>Hello, World!')
).listen(port, '127.0.0.1')

console.log('Server running at local host port=' + port)
    使用 stekin 编译它 (请用合适的路径替换下面的 stekin, 或者将编译生成的 stekin 可执行程序加入 PATH)
stekin -i require < main.stkn > main.js
    生成的 JS 代码类似 (下面这是经过去除额外括号与重新排版的, 实际上现在 Stekinscript 生成的代码真是惨不忍睹)
(function () {
    const s_http = require("http");
    s_http.createServer(function (s_request, s_response) {
        s_response.writeHead(200, {
            "Content-Type": "text/html"
        });
        s_response.end("<html><body>Hello, World!");
    }).listen(8888, "127.0.0.1");
    console.log("Server running at local host port=8888");
})();
    然后使用 node 来运行它, 就在本地搭建了一枚服务器
node main.js
Server running at local host port=8888
    访问 http://localhost:8888/ 就可以看到服务器响应了.

Makefile

Permanent Link: ?p=499 Load full text

Post tags:

 NodeJS
 Stekin
 Web Server
 Tutorial


. Back to Bit Focus
NijiPress - Copyright (C) Neuron Teckid @ Bit Focus
About this site