S3 に保存する画像 URL の配列をアップロードしています。コードは機能しますが、非同期で実行されていません。コンソールへのタイム スタンプは、最初にすべての画像がフェッチされてバッファリングされ、次に s3 に順次保存されることを示しているように見えます。100 個の画像の配列を実行しましたが、最初の画像は 100 番目の画像が取得されるまで s3 に送信されませんでした。少なくとも、画像リクエストのコールバックからコンソールでタイムスタンプのストリームを取得すると、そのように見えます.「s3への保存」タイムスタンプは、最後の画像コールバックのタイムスタンプが付けられるまで開始されません. 私はノードにかなり慣れていません.2日間の実験の後、私はこれを解読していません.
私もそれを直接パイプしようとしましたが、それにはすべてのファイルに content-length を設定する必要があり、そうでないものもあります。最初は getImageFromUrl を 1 つの関数にまとめていましたが、問題がどこにあるのかを突き止めるのに役立つように、それを 3 つの小さな関数に分割しました。s3 には request、knox、async.each イテレータには caolan の async ライブラリを使用しています。コードは次のとおりです。
var images2get = req.body.images2get; // an array of image urls to be fetched and saved to s3
var startTime = (new Date()).getTime();
//iterate over the array and get each image, save to S3
var imageNumber = 0; // this needs to come before the iterator so it's defined
async.each(images2get, getImageFromUrl, function(err){
if(err) {
console.log('async each failed for images2get');
} else {
res.send(200);
}
});
function getImageFromUrl(url2fetch, nextImage){
var options = {encoding: null,
url: url2fetch,
method: 'GET',
timeout: 10*1000
}
request(options, function(err, fetchResponse, body){
if(!err && fetchResponse && fetchResponse.statusCode == 200) {
nextImage(); //we've got the image, call the iterator to fetch the next one
var s3Config = prepareImageForS3(fetchResponse, url2fetch);
saveToS3(body, s3Config);
} else {
//there was a problem fetching the url
console.log('Error ' + fetchResponse.statusCode + ' Failed to get image from ', url2fetch.absolute);
nextImage();
}
});
};
function prepareImageForS3(fetchResponse, url2fetch) {
console.log('preparing image ' + imageNumber + ' at ', (Date.now() - startTime));
imageNumber += 1;
var filename = '/' + userId + '/' + pageId + '/image' + imageNumber;
var headers = {
'Content-Type': fetchResponse.headers['content-type'],
'x-amz-acl': 'public-read'
};
return{
'filename': filename,
'filetype': 'image',
'filenumber': imageNumber,
'headers': headers,
'replaceSrc': true,
'url': url2fetch
};
};
function saveToS3(file, s3Config) {
s3Client.putBuffer(file, s3Config.filename, s3Config.headers, function(err, res){
console.log('image ' + imageNumber + ' submitting to s3 at ', (Date.now() - startTime));
//console.log('response from s3 save from url, status:', res.statusCode, 'url:', res.req.url);
if(!err && res.statusCode === 200 && s3Config.replaceSrc) {
console.log('image ' + imageNumber + ' saved to s3 at ', (Date.now() - startTime));
} else {
console.log('failed to save image to S3 from ' + res.req.url)
}
});
};