think
is a global object that contains lots of useful methods and functions which can use anywhere of your application without require
.
The start time of service, a unix timestamp.
The current environment of application, it may be one of the three possable values, you can set it when application start:
development
The development environment, application will automatically update itself with modified files.testing
The testing environment.production
The production environment, when application deploy online.The name of project directory, you can set it when application start, the default value is:
think.dirname = {
config: 'config', // The config file directory
controller: 'controller', // Directory of controller
model: 'model', // Directory of model
adapter: 'adapter', // Directory of adapter
logic: 'logic', // Directory of logic
service: 'service', // Directory of service
view: 'view', // Directory of view
middleware: 'middleware', // Directory of middleware
runtime: 'runtime', // Directory of runtime
common: 'common', // Directory of common functions
bootstrap: 'bootstrap', // the start directory of application
locale: 'locale' // Directory of locale
}
The port of application runs, which can assign before application start, if assigned to some value, application will ignore the port value in the config file.
Whether application is run under command line mode, false by default. if it is under command line mode, this variable return command arguments. You start command line mode by run:
node www/index.js /home/index/test
The current language of system, it read from the environment, which maybe empty in windows system.
The current mode of application, framework support two mode in project:
think.mode_normal
multiple modules mode, directory of project is separated to Controller, View, Logic and some other modules.think.mode_module
multiple modules mode, but more stringent separate project with modules than normal mode.The current version of ThinkJS.
The list of modules of project.
The path of ThinkJS code.
The path where lib/
of ThinkJS is.
The root path of project, which is defined in www/index.js
The path of app directory, which is defined in www/index.js
The path of static resource directory, which is defined in www/index.js
Create a class dynamically, which inherit from think.base
by default. you can use class
to create class in ES6 if project is using ES6.
// inherit from think.base
var Cls1 = think.Class({
getName: function(){
}
})
var Cls2 = think.Class({
getName: function(){
}
}, true);
// inherit from Cls2
var Cls3 = think.Class(Cls2, {
init: function(name){
this.name = name;
},
getName: function(){
}
})
// instantiate a class which will call `init` function automatically
var instance = new Cls3('thinkjs');
target
{Object} directory objectsource1
{Mixed} source objectreturn
{Object} directory objectIt will copy methods or functions from source1, source2 and some other object to target
object, it is similar to the $.extend
in jQuery
.
Deep copy by default, you can assign the first arugment to false
if you want shallow copy.
think.extend({}, {name: 'foo'}, {value: 'bar'});
// returns
{name: 'foo', value: 'bar'}
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is Boolean type or not.
think.isBoolean(true); //true
think.isBoolean(false); //true
think.isBoolean('string'); //false
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is Number type or not.
think.isNumber(1); //true
think.isNumber(1.21); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is object type or not.
think.isObject({}); //true
think.isObject({name: "welefen"}); //true
think.isObject(new Buffer('welefen')); //false
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is string type or not.
think.isString("xxx"); // true
think.isString(new String("xxx")); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is function type or not.
think.isFunction(function(){}); //true
think.isFunction(new Function("")); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is date type or not.
think.isDate(new Date()); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is regular expression or not.
think.isRegExp(/\w+/); //true
think.isRegExp(new RegExp("/\\w+/")); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether whether this object is error type or not.
think.isError(new Error("xxx")); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is empty or not.
// check is empty or not
think.isEmpty({}); //true
think.isEmpty([]); //true
think.isEmpty(""); //true
think.isEmpty(0); //true
think.isEmpty(null); //true
think.isEmpty(undefined); //true
think.isEmpty(false); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is array or not.
think.isArray([]); //true
think.isArray([1, 2]); //true
think.isArray(new Array(10)); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is IP4 or not.
think.isIP4("10.0.0.1"); //true
think.isIP4("192.168.1.1"); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is IP6 or not.
think.isIP6("2031:0000:130f:0000:0000:09c0:876a:130b"); //true
think.isIP6("2031:0000:130f::09c0:876a:130b"); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is IP or not.
think.isIP("10.0.0.1"); //true
think.isIP("192.168.1.1"); //true
think.isIP("2031:0000:130f:0000:0000:09c0:876a:130b"); //true ip6
file
{Mixed} the path to checkreturn
{Boolean}Check whether the path is file or not, if file did't exist, return false.
think.isFile("/home/welefen/a.txt"); //true
think.isFile("/home/welefen/dirname"); //false
file
{Mixed} the path to checkreturn
{Promise}Async check whether the path is file or not, return a Promise object. You can use this function after version 2.1.5.
dir
{Mixed} the path to checkreturn
{Boolean}Check whether this path is directory or not. if not, return false.
think.isDir("/home/welefen/dirname"); //true
dir
{Mixed} the path to checkreturn
{Promise}Async check whether the path is directory or not, return a Promise object. You can use this function after version 2.1.5.
date
{Date} format
{String} date format string, default is YYYY-MM-DD HH:mm:ssreturn
{String}return a formatted date string by format parameter, format string should be like YYYY-MM-DD HH:mm:ss
:
let str = think.datetime();
//str is 2016-02-01 10:00:00
//
let str1 = think.datetime(new Date, 'YYYY-MM-DD');
// str1 is 2016-02-01
You can use this function after version 2.1.5.
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is buffer object or not.
think.isBuffer(new Buffer(20)); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is string type of number or not.
think.isNumberString(1); //true
think.isNumberString("1"); //true
think.isNumberString("1.23"); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is promise object or not.
think.isPromise(new Promise(function(){})); //true
think.isPromise(getPromise()); //true
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is http object or not.
think.isHttp(http); // true
path
{String} the path of directory or filereturn
{Boolean}Check whether this file or directory can write or not. if not, return false.
obj
{Mixed} object which need to checkreturn
{Boolean}Check whether this object is prevent type of promise or not, through think.prevent()
will generate this type of promise.
p
{String} the name of directorymode
{Number} the permission of directory , 0777 by default.Function will create directory recursively, if directory is exist. this function will modify the permission of the directory.
// if /home/welefen/a/b/ didn't exist
think.mkdir("/home/welefen/a/b");
think.mkdir("home/welefne/a/b/c/d/e"); // create directory recursively
p
{String} the path of directory to delete.reserve
{Boolean} whether to keep this directory or not, if value is true, this function will only delete subdirectory.return
{Promise}Function will delete directory recursively, if directory is not exist, this function will return directly. or this function will return a promise object, then you can use its then
to operate.
function rmTmp(){
think.rmdir('/foo/bar').then(function(){
// some operation
})
}
if use Generator Function
, you can use yield
:
function * rmTmp(){
yield think.rmdir('/foo/bar');
// some operation
}
p
{String} the path of directorymode
{Number} the permission of directory , 0777 by default.Change the permission of directory, if directory didn't exist, function will return null directly.
think.chmod("/home/welefen/a", 0777);
str
{String} the string which need to generate md5.return
{String} md5 valueGenerate md5 value.
think.md5('thinkjs');
// returns
7821eb623e0b1138a47db6a88c3f56bc
return
{Object} Deferred objectCreate a Deferred
object, which is a shortcut of Promise
. Sometimes have to use this function with some operation like setTimeout
, event
, though this is not a recommend way.
// the way using Deferred
var fn = function(){
var deferred = think.defer();
process.nextTick(function(){
if(xxx){
deferred.resolve(data);
}else{
deferred.reject(err);
}
})
return deferred.promise;
}
The way using Deferred
is much cleaner than the way using new Promise
.
// the way using new Promise
var fn = function(){
return new Promise(function(resolve, reject){
process.nextTick(function(){
if(xxx){
resolve(data);
}else{
reject(err);
}
})
})
}
Notice: asynchronous callback operations DONT use the Deferred
way, instead of encapsulate callback
to Promise
with using think.promisify
.
fn
{Function} function which to be promisifyreceiver
{Object} where is this
point to.Encapsulate asynchronous functions to Promise quickly, the last argument of asynchronous functions must be a callback, which has an error handler of first argument.
var fs = require('fs');
// function which to get file content
var getContent = function(filePath){
// encapsulate readFile to Promise
var readFilePromise = think.promisify(fs.readFile, fs);
// read file content
return readFilePromise(filePath, 'utf8');
}
// get file content
getContent('/foo/bar/file.txt').then(function(content){
console.log(content);
}).catch(function(err){
console.error(err.stack);
})
err
{Error} Error objectreturn
{Promise} reject promiseReturn a reject promise, and the difference between this and Promise.reject
is this function will print error message automaticallly, which can avoid calling catch
function to print error message by hand.
// use Promise.reject
var fn = function(){
return Promise.reject(new Error('xxx'));
}
//but need to print error massage with `catch` by hand.
fn().catch(function(err){
console.error(err.stack);
})
// use think.reject
var fn = function(){
return think.reject(new Error("xxx"));
}
// will print formatted error message automactically.
fn();
The alias of modules is co
name
{String} class nametype
{String} type (controller | model | logic ...)module
{String} module namebase
{String} find base class if cannot find moduleFind class with type or name of class. if cannot find module, program will find module in common module, if still cannot find module, program will the baseclass.
// find user controller in home module
// if cannot find, will find in common module
// if still cannot find, will find in base controller
think.lookClass("user", "controller", "home");
// find user controller in admin module
think.lookClass("admin/user", "controller");
module
{String} module nametype
{String} type, like controller, model, logicprefix
{String} prefixGet the path of module based on current project mode.
let path = think.getPath('home', 'controller');
If root path of current project is /foo/bar
, then the return path is:
think.mode_normal
then the path is /foo/bar/app/controller/home
think.mode_module
then the path is /foo/bar/app/home/controller
name
{String} flag
{Boolean}file
{String} the file to loadTo load a file safely, if file didn't exist, function will return null, and print error message at the same time.
return a special reject promise
, this promise can stop follow-up work, and not report error.
msg
{String | Error} messagetype
{String} typeshowTime
{Number | Boolean} whether show time or not.Print logs, which contains time, type and some other information.
think.log('WebSocket Status: closed', 'THINK');
//writes '[2015-09-23 17:43:00] [THINK] WebSocket Status: closed'
think.log(new Error('error'), 'ERROR');
//writes '[2015-09-23 17:50:17] [Error] Error: error'
think.log('/static/module/jquery/1.9.1/jquery.js', 'HTTP', startTime);
//writes '[2015-09-23 17:52:13] [HTTP] /static/module/jquery/1.9.1/jquery.js 10ms'
think.log('/static/module/jquery/1.9.1/jquery.js', 'HTTP', null);
//writes '[HTTP] /static/module/jquery/1.9.1/jquery.js'
think.log(function(colors){
return colors.yellow('[WARNING]') + ' test';
});
//writes '[WARNING] test'
By the way, colors
is a module named colors
in npm modules.
name
{String} config namevalue
{Mixed} config valuedata
{Object} config objectRead or setup config, it could be the global config object.
// get the config
let value = think.config('name');
// get config in admin module
let value = think.config('name', undefined, 'admin');
// write into config
think.config('name', 'value');
module
{String} module namereturn
{Object}Get all config of module, which contains config of module, comon module and the framework default config.
// get all config of admin module
let configs = think.getModuleConfig('admin');
Register, get and execute hook, what can be appended or modified if need.
think.hook('view_template');
//returns
['locate_template']
// replace ex-hook
think.hook('view_template', ['locate_template1']);
// insert before old one
think.hook('view_template', ['locate_template1'], 'prepend');
// insert after old one
think.hook('view_template', ['locate_template1'], 'append');
think.hook('view_template', null);
let result = think.hook('view_template', http, data);
//result is a promise
Register, create, get and execute middleware.
// analyzing XML example
var ParseXML = think.middleware({
run: function(){
var http = this.http;
return http.getPayload().then(function(payload){
var data = xmlParse.parse(payload); // use a xml parser, this xmlParse here is an example
http._post = data; // assign parsed data to http._post, then can get data from http._post('xxx')
});
}
});
let Cls1 = class extends think.middleware.base {
run(){
let http = this.http;
}
}
middleware can be sample function, or complex class.
// register a functional middleware
think.middleware('parse_xml', http => {
})
// redister a class middleware
// it will call run automatically
let Cls = think.middleware({
run: function(){
let http = this.http;
}
});
think.middleware('parse_xml', Cls);
let middleware = think.middleware('parse_xml');
let result = think.middleware('parse_xml', http);
//result is a promise
Create, register, get and execute adapter.
// create an adapter
var Cls = think.adapter({
});
// create a session adapter, which instance of session base class
var Cls = think.adapter('session', 'base', {
})
// create a session adapter in ES6
let Cls = class extends think.adapter.session {
}
// register some type of session adapter
think.adapter('session', 'xxx', Cls);
// get file type of session adapter
let Cls = think.adapter('session', 'file');
let Adapter = think.adapter('session', 'file');
let instance = new Adapter(options);
instance
{Object} instance of objectRegister a instance object to garbage collection queue, the instance object must have gcType
method and gc
function.
Something like cache or session which have expiration time, when after expire need to clean up.framewokr offered some handlers to clean expired file.
let Cls = class extends think.adapter.cache {
init(options){
super.init(options);
this.gcType = 'xFileCache';
think.gc(this);
}
gc(){
// find expired content to clean.
}
}
req
{Object} request objectres
{Object} response objectreturn
{Promise}Base on request and response packed into http object, by the way, req and res could be other obecjt by custom.
// based on an url object packed into a http object, which is useful to command mode calling.
think.http('/index/test').then(http => {
});
length
{Number} the length of generate string, 32 by defaultGenerate a random string.
http
{Object} http objectGenerate a session, and write it to http object, if exist, return directly.
Create and execute a controller
// create controller, instance of think.controller.base
let Cls = think.controller({
})
// create controller, instance of think.controller.rest
let Cls = think.controller('rest', {
})
// create a controller by using ES6
let Cls1 = class extends think.controller.base {
}
// instance of user controller belong to home module
let instance = think.controller('user', http, 'home');
Create and execute logic
// create logic, which instance of think.logic.base
let Cls = think.logic({
})
// create logic by using ES6
let Cls1 = class extends think.logic.base {
}
// instance of user logic which is belong to home
let instance = think.logic('user', http, 'home');
Create or get model。
// Create a model
let model = think.model({
getList: function(){
}
});
// in ES6 , instance of think.model.base class directly
let model = class extends think.model.base {
getList(){
}
}
// create a model which instance of mongo model
let model = think.model('mongo', {
getList: function(){
}
});
// in ES6, instance of think.model.mongo class directly
let model = class extends think.model.mongo {
getList(){
}
}
let configs = {
host: '127.0.0.1',
name: 'user'
}
// get user model which is belong to home module.
let instance = think.model('user', configs, 'home');
Create or get service。
// Create a service class
let service = think.service({
})
// in ES6 , instance of think.service.base class directly
let service = class extends think.service.base {
}
service base class based on think.base,so can use functions in think.base.
if don't want to write serivce to class, so it's not necessary to create by using this way.
// get post service which belong to home module, passed a `{}`
// if got service is a class, it will be instancing automatically
think.service('post', {}, 'home');
name
{String} cache keyvalue
{Mixed} cache valueoptions
{Object} cache optionsreturn
{Promise} return a PromiseGet, setup or delete cache, value is undefined
means read cache, value is null
means delete cache.
if value assigned to Function
means read cache but when cannot got a result, this function will be calling, then return the function return value which has been setup to cache.
// get cache
think.cache('name').then(data => {});
// setup the type of cache, read cache from redis for example
think.cache('name', undefined, {type: 'redis'});
// if cache userList is not exist, then query the database, assign return value to cache
think.cache('userList', () => {
return think.model('user').select();
});
// setup cache
think.cache('name', 'value');
// delete cache
think.cache('name', null);
key
{String} the key which need to getdata
{Array} argumentsGet the corresponding value based on language, the current language can get from think.lang
, which can setup when system start.
think.locale('CONTROLLER_NOT_FOUND', 'test', '/index/test');
//returns
'controller `test` not found. url is `/index/test`.'
Register, get or execute validation.
// register the validate type is not_number
think.validate('not_number', value => {
return !(/^\d+$/.test(value));
})
let fn = think.validate('not_number');
let result = think.validate({
name: {
value: 'name',
required: true,
not_number: true
},
pwd: {
value: 'xxx',
required: true,
minLength: 6
}
});
// if result is isEmpty, it means result is expected.
if(think.isEmpty(result)){
}
key
{String} callback
{Function}Execute await, to avoid a long-running operation has been called many times,
For example, one user request that get data from a remote interface can not be processed in time will result in a large number of similar requests, it's a wasting of resources. So these users can share a common request to the remote interface.
import superagent from 'superagent';
export default class extends think.controller.base {
* indexAction(){
let result = yield think.await('get_xxx_data', () => {
let req = superagent.post('xxxx');
let fn = think.promisify(req.end, req);
return fn();
});
this.success(result);
}
}
pkg
{String} module nameLoad module, if module not exist, module will been install automatically.
// if mysql module exist, project will install it with npm.
let mysql = think.npm('mysql');
// load a specify version of mysql
let mysql = think.npm('mysql@2.0.0')
err
{Error | Promise | String} error informationaddon
{Error | String} addon error meesage.Formatting error message, make some system error message completely.
let error = think.error(new Error('xxx'));
let promise = Project.reject(new Error('xxx'));
promise = think.error(promise)
Add catch for promise automatically, to catch error message.
status
{Number} status numberhttp
{Object} contained http objectlog
{Boolean} whether log error message or notWhen system is abnormal like system error, page not found, permission denied, then render the right page.
while creating project, it will generate file src/common/controller/error.js
in common module, which is specially use for handle error state.
Default support types of error are: 400
, 403
, 404
, 500
, 503
.
According to the project's need, it can be modified like error page or extension.
export default class extends think.controller.base {
indexAction(){
if(xxxx){
let error = new Error('not found');
// assign error information to http object, to render with template
this.http.error = error;
return think.statusAction(404, this.http);
}
}
}
think.base: More information read here
think.http.base: More information read here