我正在尝试为我的nodejs服务器应用创建一个上传中间件。
我正在使用打字稿:
/// <reference path="./Scripts/typings/express/express.d.ts" />
/// <reference path="./Scripts/typings/async/async.d.ts" />
import file = module('modules/fileupload_file');
import async = module('async');
export class FileUpload {
private uploadDelegate: any;
constructor(options) {
this.uploadDelegate = options.adapter || new file.filesystem(options);
console.log(this.uploadDelegate);
}
middleware(req: ExpressServerRequest, res: ExpressServerResponse, next) {
if (typeof req.files === 'undefined' || Object.keys(req.files).length === 0) {
return next()
}
async.each( Object.keys(req.files), (field, cb) => {
var files = req.files[field],
filesArray = [];
if (!Array.isArray(files))
files = [files];
async.each(files, (file, cb1) => {
filesArray = [];
if (typeof file.path === 'undefined' || file.size === 0) {
return cb1(null);
}
console.log(this);
this.uploadDelegate.put(file, function (error, storedFile) {
filesArray.push(storedFile);
cb1(null);
});
}, (err: string) => {
console.log(err);
console.log(field);
console.log(filesArray);
req.body[field] = filesArray;
cb(null);
});
}, next);
}
}
这变成了:
var file = require("./modules/fileupload_file");
var async = require('async');
var FileUpload = (function () {
function FileUpload(options) {
this.uploadDelegate = options.adapter || new file.filesystem(options);
console.log(this.uploadDelegate);
}
FileUpload.prototype.middleware = function (req, res, next) {
var _this = this;
if (typeof req.files === 'undefined' || Object.keys(req.files).length === 0) {
return next();
}
async.each(Object.keys(req.files), function (field, cb) {
var files = req.files[field], filesArray = [];
if (!Array.isArray(files))
files = [files];
async.each(files, function (file, cb1) {
filesArray = [];
if (typeof file.path === 'undefined' || file.size === 0) {
return cb1(null);
}
console.log(_this);
_this.uploadDelegate.put(file, function (error, storedFile) {
filesArray.push(storedFile);
cb1(null);
});
}, function (err) {
console.log(err);
console.log(field);
console.log(filesArray);
req.body[field] = filesArray;
cb(null);
});
}, next);
};
return FileUpload;
})();
exports.FileUpload = FileUpload;
像这样使用它:
app.post('/job/:name', myupload_middleware, function (req, res) {
我现在的问题是:
TypeError: Cannot call method 'put' of undefined
第行:_this.uploadDelegate.put(file, function (error, storedFile) {
在构造函数中我看到this.uploadDelegate已经设置好了。 console.log(_this)告诉我这个范围不是我期望的范围?
{ ArrayBuffer: [Function: ArrayBuffer],
Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
Uint8ClampedArray: { [Function: Uint8ClampedArray] BYTES_PER_ELEMENT: 1 },
Int16Array: { [Function: Int16Array] BYTES_PER_ELEMENT: 2 },
Uint16Array: { [Function: Uint16Array] BYTES_PER_ELEMENT: 2 },
Int32Array: { [Function: Int32Array] BYTES_PER_ELEMENT: 4 },
Uint32Array: { [Function: Uint32Array] BYTES_PER_ELEMENT: 4 },
Float32Array: { [Function: Float32Array] BYTES_PER_ELEMENT: 4 },
Float64Array: { [Function: Float64Array] BYTES_PER_ELEMENT: 8 },
DataView: [Function: DataView],
DTRACE_NET_SERVER_CONNECTION: [Function],
DTRACE_NET_STREAM_END: [Function],
DTRACE_NET_SOCKET_READ: [Function],
DTRACE_NET_SOCKET_WRITE: [Function],
DTRACE_HTTP_SERVER_REQUEST: [Function],
DTRACE_HTTP_SERVER_RESPONSE: [Function],
DTRACE_HTTP_CLIENT_REQUEST: [Function],
DTRACE_HTTP_CLIENT_RESPONSE: [Function],
COUNTER_NET_SERVER_CONNECTION: [Function],
COUNTER_NET_SERVER_CONNECTION_CLOSE: [Function],
COUNTER_HTTP_SERVER_REQUEST: [Function],
COUNTER_HTTP_SERVER_RESPONSE: [Function],
COUNTER_HTTP_CLIENT_REQUEST: [Function],
COUNTER_HTTP_CLIENT_RESPONSE: [Function],
global: [Circular],
process:
{ title: 'Administrator: Node.js command prompt - node app.js',
version: 'v0.10.12',
moduleLoadList:
[ 'Binding evals',
'Binding natives',
'NativeModule events',
'NativeModule buffer',
'Binding buffer',
'NativeModule assert',
'NativeModule util',
'NativeModule path',
'NativeModule module',
'NativeModule fs',
'Binding fs',
'Binding constants',
'NativeModule stream',
'NativeModule _stream_readable',
'NativeModule _stream_writable',
'NativeModule _stream_duplex',
'NativeModule _stream_transform',
'NativeModule _stream_passthrough',
'NativeModule http',
'NativeModule net',
'NativeModule timers',
'Binding timer_wrap',
'NativeModule _linklist',
'Binding cares_wrap',
'NativeModule url',
'NativeModule punycode',
'NativeModule querystring',
'NativeModule freelist',
'Binding http_parser',
'NativeModule crypto',
'Binding crypto',
'NativeModule string_decoder',
'NativeModule tty',
'Binding tty_wrap',
'NativeModule zlib',
'Binding zlib',
'NativeModule os',
'Binding os',
'NativeModule console',
'Binding signal_wrap',
'Binding tcp_wrap',
'NativeModule cluster',
'NativeModule child_process',
'NativeModule dgram',
'Binding udp_wrap',
'Binding process_wrap' ],
versions:
{ http_parser: '1.0',
node: '0.10.12',
v8: '3.14.5.9',
ares: '1.9.0-DEV',
uv: '0.10.11',
zlib: '1.2.3',
modules: '11',
openssl: '1.0.1e' },
arch: 'x64',
platform: 'win32',
argv:
[ 'node',
'D:\\GitHub\\unix-node-js-samples\\AzureHelloWorld\\app.js' ],
execArgv: [],
env:
{ ALLUSERSPROFILE: 'C:\\ProgramData',
AMDAPPSDKROOT: 'C:\\Program Files (x86)\\AMD APP\\',
APPDATA: 'C:\\Users\\Administrator\\AppData\\Roaming',
CommonProgramFiles: 'C:\\Program Files\\Common Files',
'CommonProgramFiles(x86)': 'C:\\Program Files (x86)\\Common Files',
CommonProgramW6432: 'C:\\Program Files\\Common Files',
COMPUTERNAME: 'SERVER-PC',
ComSpec: 'C:\\Windows\\system32\\cmd.exe',
FP_NO_HOST_CHECK: 'NO',
HOMEDRIVE: 'C:',
HOMEPATH: '\\Users\\Administrator',
LOCALAPPDATA: 'C:\\Users\\Administrator\\AppData\\Local',
LOGONSERVER: '\\\\SERVER-PC',
NUMBER_OF_PROCESSORS: '8',
OS: 'Windows_NT',
Path: 'C:\\Users\\Administrator\\AppData\\Roaming\\npm;C:\\Program Files
\\nodejs\\;C:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C:\\Program Files (x86)
\\AMD APP\\bin\\x86;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbe
m;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\ATI
Technologies\\ATI.ACE\\Core-Static;C:\\Program Files (x86)\\Microsoft ASP.NET\\A
SP.NET Web Pages\\v1.0\\;C:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Bi
nn\\;C:\\Program Files\\MATLAB\\R2012b\\runtime\\win64;C:\\Program Files\\MATLAB
\\R2012b\\bin;C:\\Program Files\\Microsoft\\Web Platform Installer\\;C:\\Program
Files (x86)\\Microsoft SDKs\\TypeScript\\;C:\\Program Files\\nodejs\\;C:\\Users
\\Administrator\\AppData\\Roaming\\npm',
PATHEXT: '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC',
PROCESSOR_ARCHITECTURE: 'AMD64',
PROCESSOR_IDENTIFIER: 'Intel64 Family 6 Model 26 Stepping 5, GenuineInte
l',
PROCESSOR_LEVEL: '6',
PROCESSOR_REVISION: '1a05',
ProgramData: 'C:\\ProgramData',
ProgramFiles: 'C:\\Program Files',
'ProgramFiles(x86)': 'C:\\Program Files (x86)',
ProgramW6432: 'C:\\Program Files',
PROMPT: '$P$G',
PSModulePath: 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\
;C:\\Program Files (x86)\\Microsoft SDKs\\Windows Azure\\PowerShell\\',
PUBLIC: 'C:\\Users\\Public',
SESSIONNAME: 'Console',
SSH_AGENT_PID: '5316',
SSH_AUTH_SOCK: '/tmp/ssh-aTYruZ5256/agent.5256',
SystemDrive: 'C:',
SystemRoot: 'C:\\Windows',
TEMP: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\1',
TMP: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\1',
USERDOMAIN: 'SERVER-PC',
USERDOMAIN_ROAMINGPROFILE: 'SERVER-PC',
USERNAME: 'Administrator',
USERPROFILE: 'C:\\Users\\Administrator',
VS110COMNTOOLS: 'C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\
Common7\\Tools\\',
windir: 'C:\\Windows' },
pid: 7776,
features:
{ debug: false,
uv: true,
ipv6: true,
tls_npn: true,
tls_sni: true,
tls: true },
_needImmediateCallback: false,
execPath: 'C:\\Program Files\\nodejs\\node.exe',
debugPort: 5858,
_getActiveRequests: [Function],
_getActiveHandles: [Function],
_needTickCallback: [Function],
reallyExit: [Function],
abort: [Function],
chdir: [Function],
cwd: [Function],
umask: [Function],
_kill: [Function],
_debugProcess: [Function],
_debugPause: [Function],
_debugEnd: [Function],
hrtime: [Function],
dlopen: [Function],
uptime: [Function],
memoryUsage: [Function],
binding: [Function],
_usingDomains: [Function],
_tickInfoBox: { '0': 0, '1': 0, '2': 0 },
_events: { SIGWINCH: [Function] },
domain: null,
_maxListeners: 10,
EventEmitter: { [Function: EventEmitter] listenerCount: [Function] },
_fatalException: [Function],
_exiting: false,
assert: [Function],
config: { target_defaults: [Object], variables: [Object] },
nextTick: [Function: nextTick],
_nextDomainTick: [Function: _nextDomainTick],
_tickCallback: [Function: _tickCallback],
_tickDomainCallback: [Function: _tickDomainCallback],
_tickFromSpinner: [Function: _tickFromSpinner],
maxTickDepth: 1000,
stdout: [Getter],
stderr: [Getter],
stdin: [Getter],
openStdin: [Function],
exit: [Function],
kill: [Function],
addListener: [Function],
on: [Function],
removeListener: [Function],
mainModule:
{ id: '.',
exports: {},
parent: null,
filename: 'D:\\GitHub\\unix-node-js-samples\\AzureHelloWorld\\app.js',
loaded: true,
children: [Object],
paths: [Object] },
_immediateCallback: [Function: processImmediate],
_errno: 'EALREADY' },
GLOBAL: [Circular],
root: [Circular],
Buffer:
{ [Function: Buffer]
isEncoding: [Function],
poolSize: 8192,
isBuffer: [Function: isBuffer],
byteLength: [Function],
concat: [Function],
_charsWritten: 38 },
setTimeout: [Function],
setInterval: [Function],
clearTimeout: [Function],
clearInterval: [Function],
setImmediate: [Function],
clearImmediate: [Function],
console: [Getter] }
答案 0 :(得分:1)
使用箭头功能可保留this
的含义。
您在这里使用箭头功能:
async.each( Object.keys(req.files), (field, cb) => {
如果您不想保留this
的范围,请改用标准函数:
async.each( Object.keys(req.files), function (field, cb) {
当您执行此操作时,您会看到已编译的JavaScript中的_this
变量将消失。
如果你想要两种意思,你可以手动存储上下文......
var _self = this;
async.each( Object.keys(req.files), function (field, cb) {
// self is the "outer this"
// this is the "inner this"