如何编写Nodejs程序
发布于 20天前 作者 tulayang 296 次浏览 来自 分享

以下来自我最新的源码中选取的内容. [By the way, nimrod is a cool language!]

[1.] 缓存层

import {equal} from '../common-util';
import client from './client';

const TIME_LOCK = 600;

function to_imagelock (task_id) {
    return `imagelocks._${task_id}`;
}

export function set_imagelock(task_id, userid, basename, f) {
    let key = to_imagelock(task_id);
    client
        .multi([
            ['hmset',  key, 'userid', userid, 'basename', basename],
            ['expire', key, TIME_LOCK]
        ])
        .exec((err, replies) => {
            if (err)
                f(err, null);
            else if (equal(replies[0], 'OK') && equal(replies[1], 1))
                f(null, true);
            else
                f(null, false);
        });
}

export function get_imagelock(task_id, f) {
    client.hgetall(to_imagelock(task_id), f);
}

export function del_imagelock(task_id, f) {
    client.del(to_imagelock(task_id), f);
}

[2.] 数据层

import * as queries from './task-queries';
import {query, connect} from './client';
import {format, rollback} from './db-util';
import {equal, not_equal} from '../common-util';

const TIME = 24 * 60 * 60 * 1000;

export function get_published_tasks(pubber_name, f) {
    query(queries.get_published_tasks, [pubber_name], f);
}

export function get_random_tasks(userid, f) {
    let random = Math.floor(Math.random() * 1e9);

    function get_gte_tasks(f) {
        query(format(queries.get_gte_tasks, [random, userid, 3]), f);
    }

    function get_lt_tasks(n, f) {
        query(format(queries.get_lt_tasks, [random, userid, n]), f);
    }

    get_gte_tasks((_err, gtes) => {
        let n;
        if (_err)
            f(_err, null);
        else if ((n = (3 - gtes.length)) > 0)
            get_lt_tasks(n, (err, lts) => { 
                if (err)
                    f(err, gtes);
                else
                    f(err, gtes.concat(lts));
            });
        else
            f(null, gtes);
    });
}

export function set_task(pubber_id, pubber_name, keyword, f) {
    query(
        format(queries.set_task, [pubber_id, pubber_name, keyword]), 
        (err, reply) => { 
            if (err)
                f(err, null, null);
            else if (equal(reply.affectedRows, 1))
                f(null, true, reply.insertId);
            else
                f(null, false, null);
        }
    );
}

// ...

[3.] 控制层

import {bad_request, server_error, send} from './server-util';
import {equal, not_equal, escape_input, escape_id} from '../common-util';
import {exists_user_by_userid} from '../dataset/user';
import {get_published_tasks, get_locked_tasks, get_finished_tasks, get_random_tasks,
        set_task, modify_task_to_locked, modify_task_to_finished} from '../dataset/task';
import {set_imagelock, get_imagelock, del_imagelock} from '../memory/imagelock';
import conf from './conf';
import fs from 'fs';
import path from 'path';

const image_mimes = [
    'image/gif',
    'image/jpeg',
    'image/png',
    'image/svg+xml',
    'image/tiff'
];

export function* show_published_tasks(ynext, next, req, res) {
    let [err, tasks] = yield get_published_tasks(req.params.username, ynext);
    if (err) 
        server_error(res);
    else {
        send(res, 200, 'OK', {'content-type':'application/json'}, tasks);
        yield* next;
    }
}

export function* create_task(ynext, next, req, res) { 
    let keyword = escape_input(req.body.keyword);
    if (equal(keyword, '')) 
        bad_request(res);
    else {
        let [err, affected] = yield set_task(
            req.session.userid, 
            req.session.username,
            keyword, 
            ynext
        );  
        if (err) 
            server_error(res);
        else if (equal(affected, false)) 
            bad_request(res);
        else {
            send(res, 201, 'Created');
            yield* next;
        }
    } 
}

// ...

[4.] 服务层

//@ •·→¸﹋ ﹌ ﹊ ˊ︽︾︿﹀︹︺︷︸︵︶﹄﹃︼︻〖【〗】«»‹›「」『』

import {auth_user, is_user, join, login, logout} from './controler/user/auth'; 
import {create_task, lock_task, push_task, save_image, accept_task_push,
        show_random_tasks, show_published_tasks, 
        show_finished_tasks, show_locked_tasks} from './controler/task';
import {create_fans, destroy_fans} from './controler/fans';
import {create_follower, destroy_follower} from './controler/follower';
import {is_media, show_media_and_comments, show_some_medias} from './controler/media';
import {is_comment, create_comment, validate_comment, update_comment, destroy_comment} from './controler/comment';
import {index_space} from './controler/space';
import * as cparser from './cookie-parser';
import conf from './conf';
import * as rocore from 'rocore';
import http from 'http';
import formidable from 'formidable';

let server = http.createServer();
let app    = rocore.createApplication();

app
    .on('found', (route, req, res) => { 
        req.cookies = cparser.parse(req.headers.cookie); 
        let incoming = new formidable.IncomingForm();
        let body = {};
        incoming.keepExtensions = conf.incoming.keepExtensions;
        incoming.uploadDir      = conf.incoming.uploadDir;
        incoming.multiples      = conf.incoming.multiples;
        incoming.maxFieldsSize  = conf.incoming.maxFieldsSize; 
        incoming
            .on('file', (name, file) => {
                if (!(body[name] instanceof Array)) {
                    body[name] = [];
                }
                body[name].push(file);
            })
            .on('field', (name, value) => { body[name] = value; })
            .on('end', () => {  
                req.body = body;  
                req.method = (req.body.__method || req.method).toLowerCase();
                app.exec(route, req, res);
            })
            .parse(req); 
    })  
    .on('notfound', (req, res) => { 
        res.writeHead(404);
        res.end('404 not found');
    })
    .post  ('/join', join)
    .post  ('/login', login)
    .get   ('/logout', auth_user, logout)
    .post  ('/users/:username/fans', auth_user, is_user, create_fans)
    .delete('/users/:username/fans', auth_user, is_user, destroy_fans)
    .post  ('/users/:username/followers', auth_user, is_user, create_follower)
    .delete('/users/:username/followers', auth_user, is_user, destroy_follower)
    .get   ('/tasks/randoms', auth_user, show_random_tasks)
    .post  ('/tasks', auth_user, create_task)
    .put   ('/tasks/:task_id/locked', auth_user, lock_task)
    .put   ('/tasks/:task_id/pushed', auth_user, push_task)
    .put   ('/tasks/:task_id/accepted', auth_user, save_image, accept_task_push)
    .get   ('/users/:username/tasks/published', auth_user, is_user, show_published_tasks) 
    .get   ('/users/:username/tasks/finished', auth_user, is_user, show_finished_tasks)
    .get   ('/users/:username/tasks/locked', auth_user, is_user, show_locked_tasks)
    .post  ('/users/:username/medias/:media_id/comments', auth_user, is_media, create_comment)
    .put   ('/users/:username/medias/:media_id/comments/:comment_id', auth_user, is_comment, update_comment)
    .delete('/users/:username/medias/:media_id/comments/:comment_id', auth_user, is_comment, destroy_comment) 
    .get   ('/users/:username/medias/:media_id', auth_user, is_media, show_media_and_comments)
    .get   ('/users/:username/medias', auth_user, is_user, show_some_medias)
    .get   ('/users/:username', auth_user, is_user, index_space)
    // ...
    ;

server
    .on('request', (req, res) => { app.match(req, res); })
    .on('error', (error) => { console.log('Server Nodejs %s', error); })
    .on('listening', () => { console.log('Server Nodejs online listening %s %d', conf.hostname, conf.port); })
    .listen(conf.port, conf.hostname)
    ;

[5.] 安装层、编译层

var traceur = require('traceur');
var rocore = require('rocore');
var fs = require('fs');
var path = require('path');
var source = '/home/king/box-fork/dist';
var target = '/home/king/box-fork-compile';

rocore.readSync([source], 0, function (type, pathname) {
    var newPath = path.join(target, pathname.replace(new RegExp('^' + source.replace(/\//g,'\/').replace(/\\/g,'\\')), ''));
    if (type === 'file') {
        if (path.extname(pathname) !== '.js') {
            console.log('copy %s %s', pathname, newPath);
            fs.writeFileSync(newPath, fs.readFileSync(pathname));
            return;
        }

        console.log('traceur %s %s', pathname, newPath);
        var src = fs.readFileSync(pathname, {encoding:'utf8'});
        var options = {};
        var compiled = traceur.compile(src, options);
        
        fs.writeFileSync(newPath, compiled, {encoding:'utf8'});
    } 
    if (type === 'directory') {
        console.log('mkdir %s', newPath);
        fs.mkdirSync(newPath);
    }
});

// ...
2 回复

没看出哪里酷,请指点

回到顶部