我有一个网络服务器,它接受来自客户端的图像,处理它们,将它们上传到 S3,将 url 批量插入我的 mongoDB,最后将 json 结果发送回客户端。
处理单个图像的工作方式如下:
router.post("/upload", function(req, res){
var form = new multiparty.Form();
form.parse(req,function(err,fields,files){
s3.upload({
Key: filename,
Bucket: bucketname,
ACL: "public-read",
Body: fs.createReadStream(filepath)
}, function(err, data){
if(err) //error handle
Model.collection.insert({"name": "name", "url" : data.Location}, function(err, result){
if(err) //error handle
res.json({result: result})
})
})
})
})
这非常有效,因为我只是将文件数据上传到 s3 -> 完成后,将 s3 的输出(url)插入数据库 -> 完成后,将 mongo 的结果作为 jsonarray 发送给客户端。
问题是 - 我的客户端 html 除了具有相同 name=images 的多个 type=file 输入,所以我可以在我的表单解析器中访问它们作为 图像[我]。上述算法重复 images.length 次。当我必须将 jsonarray 结果返回给客户端时,问题就出现了,因为我必须等待所有异步 S3 上传-> mongo 插入完成,而且我无法确定该工作的回调方式和位置.
我试过的有以下几种:
[data.Location]) 填充一个数组。将它们批量插入到mongoDB中,并在回调中将jsonarray结果返回给客户端。这没有用,因为 mongo insert 不等待 S3 上传。if (currentIndex = images.length),返回 jsonarray 结果。这不能准确工作,因为我不知道哪些图像会最后(不同尺寸)。我应该如何设计算法来批量上传 s3,批量插入到 mongo,将结果包括 s3 url、文件名等作为 jsonarray 返回给客户端?
提前致谢!
最佳答案
我通常使用 Promises 解决此类问题,请参阅:Bluebird .
然后您可以使用 Promise.all() 在 S3 上进行批量上传,一旦您获得该回调,您就可以批量插入到 Mongo 中,完成后,运行最终回调。或者,您可以做一个批处理来完成两件事:upload->insert to mongo,当所有这些都完成后,返回最终回调。这将取决于您的服务器以及您要一次上传的文件数量。您还可以使用 Promise.map() 并将 concurrency 选项设置为您想要运行的任何并发任务。
伪代码示例:
假设 getFiles、uploadFile 和 uploadToMongo 返回一个 Promise 对象。
var maxConcurrency = 10;
getFiles()
.map(function(file){
return uploadFile(file)
.then(uploadToMongo)
},{concurrency: maxConcurrency})
.then(function(){
return finalCallback();
}).catch(handleError);
示例,如何手动“promisify* S3:
function uploadMyFile(filename, filepath, bucketname) {
return new Promise(function(resolve, reject){
s3.upload({
Key: filename,
Bucket: bucketname,
ACL: "public-read",
Body: fs.createReadStream(filepath)
}, function(err, data){
//This err will get to the "catch" statement.
if (err) return reject(err);
// Handle success and eventually call:
return resolve(data);
});
});
}
您可以将其用作:
uploadMyFile
.then(handleSuccess)
.catch(handleFailure);
一切都很好很漂亮!
关于node.js - 我应该如何批量上传到 s3 并通过最终回调从 nodeJS 网络服务器插入到 MongoDB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34512559/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar