Skip to content

Instantly share code, notes, and snippets.

@ishiduca
Created October 7, 2011 13:06
Show Gist options
  • Save ishiduca/1270236 to your computer and use it in GitHub Desktop.
Save ishiduca/1270236 to your computer and use it in GitHub Desktop.
部分適用メソッドを使って遅延評価
// 部分適用メソッド
if (! Function.prototype.papply) {
Function.prototype.papply = function (thisObject, args) {
var slice = Array.prototype.slice;
var func = this;
return function () {
args = args.concat(slice.apply(arguments));
return func.apply(thisObject, args);
};
};
}
// startメソッドの引数の関数を順番に実行していく
// 次の関数を実行するタイミングは、release メソッドが呼ばれた時
function Queue (startDelay) {
this.works;
this.startDelay = startDelay || 0;
}
(function () {
Queue.prototype = {
start: function () {
this.works = Array.prototype.slice.apply(arguments);
if (! this.startDelay) return this.release();
},
release: function (f) {
var func, result;
if (f && typeof f === 'function') result = f();
if (this.works && this.works.length > 0) {
func = this.works.shift();
return func(); //func(result);
}
}
};
})();
var http = require('http'),
url = require('url');
;
function HTTPClient (config) {
config = config || {};
this['redirectOk'] = config['redirectOk'] || false;
this['cookie'] = config['cookie'];
this['referer'] = config['referer'];
}
(function () {
HTTPClient.prototype.request = function (/* method, uriStr, headers, body, callback */) {
var args = Array.prototype.slice.apply(arguments),
method = args.shift().toUpperCase(),
uriStr = args.shift(),
callback = args.pop(),
headers = args.shift() || {},
body = args.shift() || null,
uri, options, path, req, that
;
if (typeof uriStr === 'function') uriStr = uriStr();
uri = url.parse(uriStr);
path = (! uri['pathname']) ? '/' :
(uri['pathname'].slice(0, 1) === '/') ? uri['pathname']
: [ '/', uri['pathname'] ].join('');
if (method === 'POST') {
headers['content-length'] = (body) ? body.length : 0;
if (! headers['content-type']) headers['content-type'] = 'application/x-www-form-urlencoded';
}
if (! headers['referer'] && this['referer']) headers['referer'] = this['referer'];
if (! headers['cookie'] && this['cookie'] ) headers['cookie'] = this['cookie'];
options = {
"method" : method,
"host" : uri['hostname'],
"port" : (uri['port']) ? uri['port'] : (uri['protocol'] === 'https') ? '443' : '80',
"path" : [ path, uri['search'] ].join(''),
"headers": headers
};
req = http.request(options);
if (method === 'POST') req.write(body);
req.end();
that = this;
req.on('error', function (e) {
console.log([ e.name, e.message ].join(': '));
});
req.on('response', function (res) {
var statusCode = res.statusCode, _location, _headers;
that['referer'] = uriStr;
if (res.headers['set-cookie']) that['cookie'] = res.headers['set-cookie'][0];
if (that['redirectOk'] && statusCode >= 300 && statusCode < 400 && res.headers['location']) {
_location = res.headers['location'];
_headers = { 'referer' : uriStr };
if (that['cookie']) _headers['cookie'] = that['cookie'];
//console.log('redirect >> ' + _location);
that.request('GET', _location /* , _headers */, function (_response) {
callback(_response, [ _location, _headers, null]);
});
} else {
callback(res, [ uriStr, headers, body ]);
}
});
};
})();
var queue = new Queue;
var client = new HTTPClient({ redirectOk : true });
var myData = {};
var body = 'mode=login&pixiv_id=xxx&pass=xyz';
var illust_id = '22134239';
var wwwPixivNet = 'http://www.pixiv.net';
var loginPhp = [ wwwPixivNet, '/login.php' ].join('');
var illustTop = [ wwwPixivNet, '/member_illust.php?mode=medium&illust_id=', illust_id ].join('');
queue.start(
client.request.papply(client, [ 'POST', loginPhp, {}, body, function (res, req) {
queue.release(report.papply(null, [ res, req ]));
} ]),
/*
client.request.papply(client, ['GET', [ wwwPixivNet, '/mypage.php' ].join(''), function (res, req) {
report(res, req);
queue.release();
} ]),
*/
client.request.papply(client, [ 'GET', illustTop, function (res, req) {
report(res,req);
var data = '';
res.setEncoding('utf-8');
res.on('data', function (chunk) { data += chunk; });
res.on('end', function () {
data = data.replace(/\n/g, '');
var reg = /<a href="(member_illust\.php\?mode=[^"]+?)"[^>]+?><img src="([^"]+?)".+?title="([^"]+?)"/;
var result = reg.exec(data);
myData['illustBig'] = [ wwwPixivNet, result[1].replace(/&amp;/g, "&") ].join('/');
console.log(myData['illustBig']);
queue.release();
});
} ]),
client.request.papply(client, [ 'GET', function () { return myData['illustBig']; }, function (res, req) {
report(res,req);
var data = '';
res.setEncoding('utf-8');
res.on('data', function (chunk) { data += chunk; });
res.on('end', function () {
data = data.replace(/\n/g, '');
var reg = /<img src="(http:\/\/img\d{2,3}[^"]+?)"/;
var result = reg.exec(data);
myData['imgSrc'] = result[1];
console.log(myData['imgSrc']);
queue.release();
});
} ]),
client.request.papply(client, [ 'GET', function () { return myData['imgSrc']; }, function (res, req) {
report(res,req);
var imgSrc = myData['imgSrc'];
var target = require('path').basename(imgSrc);
console.log(imgSrc + " >> " + target);
var writeStream = require('fs').createWriteStream(target);
writeStream.on('error', function (exception) {
throw exception;
});
writeStream.on('close', function () {
console.log('writeStream say "close"');
});
res.on('data', function (chunk) {
writeStream.write(chunk);
});
res.on('end', function () {
writeStream.end();
console.log('response say "end"');
});
} ])
);
function report(res, req) {
console.log([ "Response-statusCode", res.statusCode ].join(': '));
console.log([ "Response-headers", JSON.stringify(res.headers) ].join(': '));
console.log([ "Request-uri", req[0] ].join(': '));
console.log([ "Request-headers", JSON.stringify(req[1]) ].join(': '));
console.log([ "Request-body", req[2] ].join(': '));
console.log('');
}
1;
@ishiduca
Copy link
Author

Function.bind が使える場面だったら、そっちを使う

function sum () {
    return [].reduce.apply(arguments, [ function (a, b) { return a + b; }, 0 ]);
}

var keihi = sum.bind(null, 250, 350); // 'null' には thisObj が入る
console.log(keihi()); // 600

var amount = keihi(630, 772, 525);
console.log(amount); // 2527

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment