如何正确构buildasynchronous节点代码

我试图通过我所拥有的“事件”数据库来工作,并根据每个事件的位置,半径,开始时间和结束时间从Instagram API中提取照片。 我已经在我的Node服务器上设置了下面的代码,但它不像我所期望的那样运行。

当我运行这个代码时,我看到的第一件事就是sending request to Instagram for [name] with min_timestamp: [timestamp]为每个事件打印sending request to Instagram for [name] with min_timestamp: [timestamp] 。 我没有想到这一点。 我希望看到这行logging的第一个事件,然后更新一个新的时间戳,直到该事件达到其结束时间。 然后事件2,遍历时间戳,等等。

最后,我会为每个事件重复一遍又一遍的相同的照片。 就好像我的代码一遍又一遍地向Instagram发出一个请求(带有初始时间戳),然后停止。

关于我的时间戳variables的注意事项:对于每个事件,我将我的minTimestampvariables设置为初始等于我的数据库中的event.start 。 这在发送给Instagram的请求中使用。 Instagram返回20张照片给我。 每张照片都有一个created_timevariables。 我抓住最近的created_timevariables,并设置我的minTimestampvariables等于它( minTimestamp = images[0].created_time; )我的下一个请求发送到Instagram(抓住接下来的20张照片)。 这将继续,直到minTimestamp不再小于endTimestamp( event.end从我的数据库中的事件)。

server.js代码:

 // modules ================================================= var express = require('express.io'); var app = express(); var port = process.env.PORT || 6060; var io = require('socket.io').listen(app.listen(port)); var request = require('request'); var Instagram = require('instagram-node-lib'); var mongoose = require('mongoose'); var async = require('async'); var bodyParser = require('body-parser'); var methodOverride = require('method-override'); var db = require('./config/db'); var Event = require('./app/models/event'); // configuration =========================================== mongoose.connect(db.url); // connect to our mongoDB database // get all data/stuff of the body (POST) parameters app.use(bodyParser.json()); // parse application/json app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form- urlencoded app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method- Override header in the request. simulate DELETE/PUT app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users var baseUrl = 'https://api.instagram.com/v1/media/search?lat='; var clientId = CLIENT-ID; Event.find({}, function(err, events) { async.eachSeries(events, function(event, callback) { var name = event.event; var latitude = event.latitude; var longitude = event.longitude; var distance = event.radius; var minTimestamp = Math.floor(new Date(event.start).getTime()/1000); var endTimestamp = Math.floor(new Date(event.end).getTime()/1000); async.whilst( function () { return minTimestamp < Math.floor(Date.now() / 1000) && minTimestamp < endTimestamp; }, function(callback) { console.log('sending request to Instagram for ' + name + ' with min_timestamp: ' + minTimestamp); request(baseUrl + latitude + '&lng=' + longitude + '&distance=' + distance + '&min_timestamp=' + minTimestamp + '&client_id=' + clientId, function (error, response, body) { if (error) { console.log('error'); return; } //JSON object with all the info about the image var imageJson = JSON.parse(body); var images = imageJson.data; var numImages = images.length; console.log(numImages + ' images returned with starting time ' + images[(numImages - 1)].created_time + ' and ending time ' + images[0].created_time); async.eachSeries(images, function(image, callback) { //Save the new object to DB Event.findOneAndUpdate( { $and: [{latitude: latitude}, {radius: distance}] }, { $push: {'photos': { img: image.images.standard_resolution.url, link: image.link, username: image.user.username, profile: image.user.profile_picture, text: image.caption ? image.caption.text : '', longitude: image.location.longitude, latitude: image.location.latitude }}}, { safe: true, upsert: false }, function(err, model) { console.log(err); } ); console.log(numImages + ' images saved to db'); callback(); }, function(err){ // if any of the file processing produced an error, err would equal that error if( err ) { // One of the iterations produced an error. // All processing will now stop. console.log('Images failed to process'); } else { console.log('All images have been processed successfully'); } }); minTimestamp = images[0].created_time; console.log('min_timestamp incremented to: ' + minTimestamp); } ); }, function (err) { } ); callback(); }, function(err){ // if any of the file processing produced an error, err would equal that error if( err ) { // One of the iterations produced an error. // All processing will now stop. console.log('An event failed to process'); } else { console.log('All events have been processed successfully'); } }); }); // routes ================================================== require('./app/routes')(app); // configure our routes // start app =============================================== console.log('Magic happens on port ' + port); // shoutout to the user exports = module.exports = app; // expose app 

答案是你错过了callback()的while位。

这里有一些代码来说明:

 var async = require('async'); var minTimestamp = 1; var endTimestamp = 10; async.whilst( function () { minTimestamp < endTimestamp; }, function(callback) { console.log('sending request to Instagram for name with min_timestamp: ' + minTimestamp); minTimestamp = minTimestamp + 1; console.log('min_timestamp incremented to: ' + minTimestamp); callback(); }, function (err) { if(err){ throw err; } } ); 

如果我运行这个没有callback() ,我得到以下输出:

 sending request to Instagram for name with min_timestamp: 1 min_timestamp incremented to: 2 

如果我把callback()我得到这个:

 sending request to Instagram for name with min_timestamp: 1 min_timestamp incremented to: 2 sending request to Instagram for name with min_timestamp: 2 min_timestamp incremented to: 3 sending request to Instagram for name with min_timestamp: 3 min_timestamp incremented to: 4 sending request to Instagram for name with min_timestamp: 4 min_timestamp incremented to: 5 sending request to Instagram for name with min_timestamp: 5 min_timestamp incremented to: 6 sending request to Instagram for name with min_timestamp: 6 min_timestamp incremented to: 7 sending request to Instagram for name with min_timestamp: 7 min_timestamp incremented to: 8 sending request to Instagram for name with min_timestamp: 8 min_timestamp incremented to: 9 sending request to Instagram for name with min_timestamp: 9 min_timestamp incremented to: 10 

所以在这里放一个callback():

  minTimestamp = images[0].created_time; console.log('min_timestamp incremented to: ' + minTimestamp); callback(); //missing callback } ); }, 
 // modules ================================================= var express = require('express.io'); var app = express(); var port = process.env.PORT || 6060; var io = require('socket.io').listen(app.listen(port)); var request = require('request'); var Instagram = require('instagram-node-lib'); var mongoose = require('mongoose'); var async = require('async'); var bodyParser = require('body-parser'); var methodOverride = require('method-override'); var db = require('./config/db'); var Event = require('./app/models/event'); // configuration =========================================== mongoose.connect(db.url); // connect to our mongoDB database // get all data/stuff of the body (POST) parameters app.use(bodyParser.json()); // parse application/json app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form- urlencoded app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method- Override header in the request. simulate DELETE/PUT app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users var baseUrl = 'https://api.instagram.com/v1/media/search?lat='; var clientId = CLIENT-ID; Event.find({}, function(err, events) { async.eachSeries(events, function(event, seriesCallback) { var name = event.event; var latitude = event.latitude; var longitude = event.longitude; var distance = event.radius; var minTimestamp = Math.floor(new Date(event.start).getTime()/1000); var endTimestamp = Math.floor(new Date(event.end).getTime()/1000); async.whilst( function () { return minTimestamp < Math.floor(Date.now() / 1000) && minTimestamp < endTimestamp; }, function(requestFinishedCallback) { console.log('sending request to Instagram for ' + name + ' with min_timestamp: ' + minTimestamp); request(baseUrl + latitude + '&lng=' + longitude + '&distance=' + distance + '&min_timestamp=' + minTimestamp + '&client_id=' + clientId, function (error, response, body) { if (error) { console.log('error'); return; } //JSON object with all the info about the image var imageJson = JSON.parse(body); var images = imageJson.data; var numImages = images.length; console.log(numImages + ' images returned with starting time ' + images[(numImages - 1)].created_time + ' and ending time ' + images[0].created_time); async.eachSeries(images, function(image, imageFinishedCallback) { //Save the new object to DB Event.findOneAndUpdate( { $and: [{latitude: latitude}, {radius: distance}] }, { $push: {'photos': { img: image.images.standard_resolution.url, link: image.link, username: image.user.username, profile: image.user.profile_picture, text: image.caption ? image.caption.text : '', longitude: image.location.longitude, latitude: image.location.latitude }}}, { safe: true, upsert: false }, function(err, model) { console.log(err); console.log('Image processed'); imageFinishedCallback(); } ); }, function(err){ // if any of the image processing produced an error, err would equal that error if( err ) { // One of the iterations produced an error. // All processing will now stop. console.log('Images failed to process'); } else { minTimestamp = images[0].created_time; console.log(numImages + ' images have been processed successfully and min_timestamp has been incremented to: ' + minTimestamp); requestFinishedCallback(); } }); } ); }, function(err){ // if any of the image processing produced an error, err would equal that error if( err ) { // One of the iterations produced an error. // All processing will now stop. console.log('Event failed to process'); } else { console.log(name + ' has been fully processed successfully with final min_timestamp of: ' + minTimestamp); } seriesCallback(); }); }, function(err){ // if any of the image processing produced an error, err would equal that error if( err ) { // One of the iterations produced an error. // All processing will now stop. console.log('Something failed to process'); } else { console.log('All events have been processed successfully'); } }); }); // routes ================================================== require('./app/routes')(app); // configure our routes // start app =============================================== console.log('Magic happens on port ' + port); // shoutout to the user exports = module.exports = app;