Promise function is not running funcation after .then - javascript

What I am trying to do is run functions that will send out messages. The problem with node js is that it does not return in sequence. I do however want each function to run in the sequence that it is coded.
Not really sure what I'm missing here.
Right now I can get it to return only message 1 and message 2 in sequence BUT I want to go all the way from callfirstmessage to callfifthmessage. When I have tried to do this they all get returned out of order.
var promise = new Promises(function(resolve, reject) {
// do some async stuff
callfirstmessage();
//resolve(data);
if (success) {
resolve(data);
} else {
reject(reason);
}
});
promise.then(function(data) {
// function called when first promise returned
return new Promises(function(resolve, reject) {
// second async stuff
callthirdmessage();
//resolve(data);
if (success) {
resolve(data);
} else {
reject(reason);
}
});
}, function(reason) {
// error handler
}).then(function(data) {
callsecondmessage();
}, function(reason) {
// second error handler
});
I have looked at a few different posts talking about this topic and I have used those suggestions. I think my issue here is not being able to successfully chain these together. I have spent a few days on this with no additional progress...I need help bad!
-----------------------edit----------------------------
I think I need to apply something similar to this .then I have found here: https://coderwall.com/p/ijy61g/promise-chains-with-node-js. But for some reason it is still sending messages at random.
Maybe, I'm just going in the completely wrong direction. :/
Below is everything I am working with
// dependencies
console.log("starting program");
var async = require('async');
var AWS = require('aws-sdk');
var Converter = require("csvtojson").Converter;
var util = require('util');
var Promises = require('pinkie-promise');
var vow = require('vow');
var s3 = new AWS.S3();
var snsTopicEMAIL = new AWS.SNS({
params: {
TopicArn: 'arn:aws:sns:xxxxxxxxxxxxxxxxxxxxxxxx'
}
});
var snsTopicSMS = new AWS.SNS({
params: {
TopicArn: 'arn:aws:sns:xxxxxxxxxxxxxxxxxxxxxxxxx'
}
});
var abort = false;
//SMS
function topDSRsms(csvJSON) {
var ytdTopReg = "";
if (csvJSON.length < 1) {
console.error("Not enough data records in CSV to compose an SMS. Aborting. count:" + csvJSON.length);
tdTopReg = "There was an error. Please contact IT for assistance.";
abort = true;
throw '';
}
ytdTopReg = "";
for (var i = 0; i < csvJSON.length; i++) {
var csvItem = csvJSON;
if (csvItem[i].KPIvalue.length > 0 && csvItem[i].KPI.length > 0) {
var KPI = " " + csvItem[i].KPI + ":" + csvItem[i].KPIvalue + "\n";
} else {
KPI = " ";
}
if (csvItem[i].TrendValue1.length > 0 && csvItem[i].Trend1.length > 0) {
var trend1 = "\n" + svItem[i].Trend1 + ":" + csvItem[i].csvItem[i].TrendValue1;
} else {
trend1 = "";
}
if (csvItem[i].TrendValue2.length > 0 && csvItem[i].Trend2.length > 0) {
var trend2 = "\n" + csvItem[i].Trend2 + ":" + csvItem[i].TrendValue2;
} else {
trend2 = "";
}
if (csvItem[i].TrendValue3.length > 0 && csvItem[i].Trend3.length > 0) {
var trend3 = "\n" + csvItem[i].Trend3 + ":" + csvItem[i].TrendValue3;
} else {
trend3 = "";
}
ytdTopReg += "\n#" + (i + 1) + KPI + csvItem[i].RankTrend + ":" + csvItem[i].RankTrendValue + trend1 + trend2 + trend3;
}
return ytdTopReg;
}
function dshSmsStr(csvJSON) {
return "DSR:" +
topDSRsms(csvJSON);
}
//email
function topDSREmail(csvJSON) {
var ytdTopReg = "";
ytdTopReg = "Top orders By Region - ";
for (var i = 0; i < csvJSON.length; i++) {
if (csvJSON.length < 1) {
console.error("Not enough data records in CSV to compose an email. Aborting.");
ytdTopReg = "There was an error. Please contact IT for assistance."
abort = true;
throw '';
//return -1;
} else {
var csvItem = csvJSON;
if (csvItem[i].KPIvalue.length > 0 && csvItem[i].KPI.length > 0) {
var KPI = " " + csvItem[i].KPI + ":" + csvItem[i].KPIvalue + "\n";
} else {
KPI = "";
}
if (csvItem[i].TrendValue1.length > 0 && csvItem[i].Trend1.length > 0) {
var trend1 = "\n" + svItem[i].Trend1 + ":" + csvItem[i].csvItem[i].TrendValue1;
} else {
trend1 = "";
}
if (csvItem[i].TrendValue2.length > 0 && csvItem[i].Trend2.length > 0) {
var trend2 = "\n" + csvItem[i].Trend2 + ":" + csvItem[i].TrendValue2;
} else {
trend2 = "";
}
if (csvItem[i].TrendValue3.length > 0 && csvItem[i].Trend3.length > 0) {
var trend3 = "\n" + csvItem[i].Trend3 + ":" + csvItem[i].TrendValue3;
} else {
trend3 = "";
}
ytdTopReg += "\n#" + (i + 1) + KPI + csvItem[i].RankTrend + ":" + csvItem[i].RankTrendValue + trend1 + trend2 + trend3 + "\n";
}
}
return ytdTopReg;
}
function dshEmailStr(csvJSON) {
return "DSR:" +
topDSREmail(csvJSON);
}
console.log("compiled totals string and customer string");
exports.handler = function(event, context) {
// Read options from the event.
console.log("Reading options from event:\n", util.inspect(event, {
depth: 5
}));
var srcBucket = event.Records[0].s3.bucket.name;
console.log("got src bucket name");
// Object key may have spaces or unicode non-ASCII characters.
var srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
console.log("src key decoded");
// Download the CSV file from S3, Extract&Load data into DynamoDB, and notify end users.
async.waterfall([
function downloadCSV(next) {
// Download the Daily Sales Highlights CSV file from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function parseCSV(response, next) {
console.log(response.ContentType);
var csvStream = AWS.util.buffer.toStream(response.Body);
var csvJSON = [];
var converter = new Converter({});
//end_parsed will be emitted once parsing finished
converter.on("end_parsed", function(jsonArray) {
console.log(jsonArray); //here is your result jsonarray
csvJSON = jsonArray;
next(null, csvJSON);
});
//read CSV from stream
csvStream.pipe(converter);
},
function updateState(csvJSON, next) {
//Update state in DynamoDB
next(null, csvJSON);
},
function notifyEndUsers(csvJSON, next) {
//Notify end users
console.log("\n\nNotifying SMS end users...\n\n");
console.log(dshSmsStr(csvJSON));
console.log("\n\nNotifying email end users...\n\n");
console.log(dshEmailStr(csvJSON));
//email
snsTopicEMAIL.publish({
Message: dshEmailStr(csvJSON)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
//SMS
var datastr = dshSmsStr(csvJSON);
var strlen = dshSmsStr(csvJSON).length;
var ranscript = false;
var completemsg1 = false;
var completemsg2 = false;
var completemsg3 = false;
var completemsg4 = false;
var completemsg5 = false;
var completemsg6 = false;
function callfirstmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(0, 150)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callsecondmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(150, 300)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callthirdmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(300, 450)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callfourthmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(450, 600)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callfifthmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(600, 750)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function one() {
new Promises(function(resolve1, reject) {
completemsg1 = callfirstmessage();
if (completemsg1 === true) {
resolve1(true);
console.log('first success');
} else {
reject(false);
console.log('first fail');
}
});
}
function two() {
new Promises(function(resolve2, reject) {
completemsg2 = callsecondmessage();
if (completemsg2 === true) {
resolve2(completemsg2);
console.log('second success');
} else {
reject(false);
console.log('second fail');
}
});
}
function three() {
new Promises(function(resolve3, reject) {
completemsg3 = callthirdmessage();
if (completemsg3 === true) {
resolve3(completemsg3);
console.log('third success');
} else {
reject(false);
console.log('third fail');
}
});
}
function four() {
new Promises(function(resolve4, reject) {
completemsg4 = callfourthmessage();
if (completemsg4 === true) {
resolve4(completemsg4);
console.log('fourth success');
} else {
reject(false);
console.log('fourth fail');
}
});
}
function five() {
new Promises(function(resolve5, reject) {
completemsg5 = callfifthmessage();
if (completemsg5 === true) {
resolve5(completemsg5);
console.log('fifth success');
} else {
reject(false);
console.log('fifth fail');
}
});
}
console.log("\n\n Begin SMS script. Data length :" + strlen + "...\n\n");
if (strlen < 150) { //one message sent
//Will complete later
ranscript = true;
} else if (strlen < 300) { //two messages sent
//Will complete later
ranscript = true;
} else if (strlen < 450) { //three messages sent
//Will complete later
ranscript = true;
} else if (strlen < 600) { //four messages sent
one().then(function() {
return two();
})
.then(function() {
return three();
})
.then(function() {
return four();
})
.then(function() {
return five();
});
ranscript = true;
} else if (strlen < 750) { //five messages sent
//Will complete later
ranscript = true;
} else {
console.log("\n\n The SMS mesages is too large to send to end users...\n\n");
}
if (ranscript === false) {
console.log("\n\n SMS script did not run \n\n");
} else if (ranscript === true) {
console.log("\n\n SMS script successfully ran \n\n");
}
}
], function(err) {
if (err) {
console.error(
'Unable to process due to an error: ' + err
);
} else {
console.log(
'Successfully processed'
);
}
context.done();
});
}

The executor for the first promise (reformatted):
var promise = new Promise(function(resolve, reject)
{ // do some async stuff
callfirstmessage();
if (success)
{ resolve(data);
} else
{ reject(reason);
}
});
doesn't resolve or reject the returned promise asynchronously. You will need to get a call back from the asynchronous operation before resolving/rejecting the returned promise. In pseudo code something more like:
var promise = new Promise(function(resolve, reject)
{ // do some async stuff
callfirstmessage( successCallBack, failCallBack);
function successCallBack( data)
{ resolve(data);
}
function failCallBack( reason)
{ reject(reason);
}
});
In reality you may have to use a call back the asynchronous operation supports, and then analyze success or failure of the operation depending on a status property located in a request or response object.

Related

Extracting value from Promise [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How can I access the value of a promise?
(14 answers)
How do I promisify native XHR?
(6 answers)
Closed 9 days ago.
I am trying to extract value from a Promise. I am able to print the result before it gets returned in a Promise.
function countTotalInvItem() {
var params = 'service=shopping&request=getshopitems&mode=count';
var jsonRes = xmlHttpSend(params).then((value) => {
if (value instanceof Promise) {
console.log('Promise found');
} else {
console.log('Promise NOT');
if (value != null) {
console.log('Value: ' + value);
} else {
console.log('NULL value');
}
}
});
}
async function xmlHttpSend(params) {
let myPromise = new Promise(function (resolve) {
var xhr = new XMLHttpRequest();
var url = 'portal?' + params;
xhr.onreadystatechange = function (response) {
if (xhr.readyState == 4 && xhr.status == 200) {
var rs = parseReturn(xhr.responseText);
console.log('ResultSet >>> ' + rs.toString());
if (
rs.success === 'true' &&
rs.resultPayloadType === 'json' &&
rs.result !== null
) {
console.log('Parsing JSON ...');
var json = JSON.parse(rs.result);
if (json === null) {
console.log('NO JSON RESULT !!!');
} else {
console.log('JSON Result Parsed: ' + json[0].count);
}
resolve(json);
} else {
console.log('RS has ERROR !!!');
resolve(null);
}
}
};
xhr.open('GET', url, true);
xhr.send();
});
}
function parseReturn(input) {
var kvArrays1 = input.split('&');
var service = null;
var sessionID = null;
var success = false;
var errorCode = -1;
var resultEncoding = null;
var resultPayloadType = null;
var result = null;
if (kvArrays1.length > 0) {
for (let i = 0; i < kvArrays1.length; i++) {
if (kvArrays1[i] != null) {
var kvArrays2 = kvArrays1[i].split('=');
if (kvArrays2 != null) {
switch (kvArrays2[0]) {
case 'service':
if (kvArrays2.length == 2) {
service = kvArrays2[1];
}
break;
case 'sessionID':
if (kvArrays2.length == 2) {
sessionID = kvArrays2[1];
}
break;
case 'success':
if (kvArrays2.length == 2) {
success = kvArrays2[1];
}
break;
case 'errorCode':
if (kvArrays2.length == 2) {
errorCode = kvArrays2[1];
}
break;
case 'resultEncoding':
if (kvArrays2.length == 2) {
resultEncoding = kvArrays2[1];
}
break;
case 'resultPayloadType':
if (kvArrays2.length == 2) {
resultPayloadType = kvArrays2[1];
}
break;
case 'result':
if (kvArrays2.length >= 2) {
result = '';
for (let j = 1; j < kvArrays2.length; j++) {
if (kvArrays2[j] == '') {
result += '=';
} else {
result = kvArrays2[j];
}
}
}
break;
}
}
}
}
}
return new ResultSet(
service,
sessionID,
success,
errorCode,
resultEncoding,
resultPayloadType,
result
);
}
class ResultSet {
constructor(
service,
sessionID,
success,
errorCode,
resultEncoding,
resultPayloadType,
result
) {
this.service = service;
this.sessionID = sessionID;
this.success = success;
this.errorCode = errorCode;
this.resultEncoding = resultEncoding;
this.resultPayloadType = resultPayloadType;
if (result != null) {
if (result.length > 0) {
this.result = atob(result);
}
}
}
toString() {
return (
'service: ' +
this.service +
'; sessionID: ' +
this.sessionID +
'; success: ' +
this.success +
'; errorCode: ' +
this.errorCode +
'; resultEncoding: ' +
this.resultEncoding +
'; resultPayloadType: ' +
this.resultPayloadType +
'; result: ' +
this.result
);
}
}
<!DOCTYPE html>
<html>
<head>
<script>
</script>
</head>
<body>
<div id="demo">
<h2>Count Total Inventory Items</h2>
<button type="button" onclick="countTotalInvItem()">Count</button>
</div>
</body>
</html>
The output as the screenshot shows with the developer console opened.
I am able to receive the response and to print out the 'count' number from the JSON that is returned.
I am missing something to pass the JSON from 'xmlHttpSend' async function to the 'countTotalInvItem' and print it as a value (which should be value of '1') ?
Thanks.
I can't get that code to run properly to try to edit it, but your function xmlHttpSend does not return anything.
It declares a variable (myPromise) but does not use it. If you want this function to return a promise, you can just do:
return new Promise(function (resolve) {
instead of
let myPromise = new Promise(function (resolve) {
It is not necessary to declare xmlHttpSend as async since it returns a promise, the purpose of async is to avoid writing promises explicitly. You should also avoid using var as much as possible, it makes your code harder to understand because of the scope it gives to the variable.
It is the same thing for the != and == in your functions, you should try to use !== and === as much as possible as it is easier to understand and to debug

Variable scope; var undefined or same var loop

Meteor.methods({
'list.messages' () {
getTwilioMessages(function(err, data) {
if (err) {
console.warn("There was an error getting data from twilio", err);
return
}
data.messages.forEach(function(message) {
if (SMS.find({
sid: message.sid
}).count() > 0) {
return;
}
var image;
if (message.numMedia > 0) {
var images = [];
Meteor.wrapAsync(client.messages(message.sid).media.list(function(err, data) {
console.log(data)
if (err) throw err;
Meteor.wrapAsync(data.media_list.forEach(function(media, index) {
mediaImage = (function() {
let mediaImg = 'http://api.twilio.com/2010-04-01/Accounts/' + media.account_sid + '/Messages/' + media.parent_sid + '/Media/' + media.sid;
return mediaImg
});
}));
images.push(mediaImage());
console.log("Just One:" + mediaImage())
console.log("IMAGESSSS " + mediaImage())
}));
message.image = mediaImage();
console.log("test" + image)
} else {
message.image = null
}
if (message.from === Meteor.settings.TWILIO.FROM) {
message.type = "outgoing";
} else {
message.type = "incoming";
}
SMS.insert(message)
});
});
getTwilioMessages();
Meteor.setInterval(getTwilioMessages, 60000);
// client.calls.get(function(err, response) {
// response.calls.forEach(function(call) {
// console.log('Received call from: ' + call.from);
// console.log('Call duration (in seconds): ' + call.duration);
// });
// });
},
I expect to see different image URL's in the data.media_list.forEach. But, it returns the same image. In the console I get the desired results.
I want these results:
message.image = 'http://api.twilio.com/2010-04-01/Accounts/3039030393/Messages/303030/media/3kddkdd'
message.image = 'http://api.twilio.com/2010-04-01/Accounts/3039sdfa393/Messages/303030/media/3asdfdfsa' inserted into the correct message.
instead I get the same URl over and over resulting in the same image
for all my messages. I guess my scope is incorrect, but I have
attempted to follow: 2ality guide on scoping and Explaining
JavaScript Scope And Closures with no luck.

TypeError: Cannot read property 'toString' of undefined - why?

Here is the line (50) where this is happening:
var meetingId = meeting._id.toString(),
And here is the full, relevant code:
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var config = require('./config'),
xlsx = require('./xlsx'),
utils = require('./utils'),
_ = require('lodash'),
url = config.DB_URL;
var meetings = [];
function findNumberOfNotesByMeeting(db, meeting, callback) {
var meetingId = meeting._id.toString(),
meetingName = meeting.name.displayValue,
attendees = meeting.attendees;
host = meeting.host;
var count = 1, pending = 0, accepted = 0;
console.log("==== Meeting: " + meetingName + '====');
_.each(attendees, function(item) {
console.log(count++ + ': ' + item.email + ' (' + item.invitationStatus + ')');
if (item.invitationStatus == 'pending') { pending++; }
else if (item.invitationStatus == 'accepted') { accepted++; }
});
console.log("*** " + attendees.length + ", " + pending + "," + accepted);
db.collection('users').findOne({'_id': new ObjectId(host)}, function(err, doc) {
var emails = [];
if (doc.emails) {
doc.emails.forEach(function(e) {
emails.push(e.email + (e.primary ? '(P)' : ''));
});
}
var email = emails.join(', ');
if (utils.toSkipEmail(email)) {
callback();
} else {
db.collection('notes').find({ 'meetingId': meetingId }).count(function(err, count) {
if (count != 0) {
console.log(meetingName + ': ' + count + ',' + attendees.length + ' (' + email + ')');
meetings.push([ meetingName, count, email, attendees.length, pending, accepted ]);
}
callback();
});
}
});
}
function findMeetings(db, meeting, callback) {
var meetingId = meeting._id.toString(),
host = meeting.host;
db.collection('users').findOne({'_id': new ObjectId(host)}, function(err, doc) {
var emails = [];
if (!err && doc && doc.emails) {
doc.emails.forEach(function(e) {
emails.push(e.email + (e.primary ? '(P)' : ''));
});
}
var email = emails.join(', ');
if (utils.toSkipEmail(email)) {
callback();
} else {
db.collection('notes').find({ 'meetingId': meetingId }).count(function(err, count) {
if (count != 0) {
var cursor = db.collection('meetings').find({
'email': {'$regex': 'agu', '$options': 'i' }
});
}
callback();
});
}
cursor.count(function(err, count) {
console.log('count: ' + count);
var cnt = 0;
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
findNumberOfNotesByMeeting(db, doc, function() {
cnt++;
if (cnt >= count) { callback(); }
});
}
});
});
});
}
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
findMeetings(db, function() {
var newMeetings = meetings.sort(function(m1, m2) { return m2[1] - m1[1]; });
newMeetings.splice(0, 0, [ 'Meeting Name', 'Number of Notes', 'Emails' ]);
xlsx.writeXLSX(newMeetings, config.xlsxFileNameMeetings);
db.close();
});
});
As you can see, the meeting variable (which I am almost 100% sure is the problem, not the _id property) is passed in just fine as a parameter to the earlier function findNumberOfNotesByMeeting. I have found some information here on SO about the fact that my new function may be asynchronous and needs a callback, but I've attempted to do this and am not sure how to get it to work, or even if this is the right fix for my code.
You're not passing the meeting object to findMeetings, which is expecting it as a second parameter. Instead of getting the meeting object, the function receives the callback function in its place, so trying to do meeting._id is undefined.
In fact, what is the purpose of the findMeetings function? It's name indicates it can either find all meetings in the database, or all meetings with a specific id. You're calling it without a meeting id indicating you might be trying to find all meetings, but its implementation takes a meeting object. You need to clear that up first.

Why Node.js script doesn't exit

I wrote code to get data from HTTP service and save it in MongoDB.
Now I test it directly from the console node script.js
The script does its job, but it doesn't exit. I have to do CTRL+C to stop it
Why does it not exit automatically? What place in the code is best for process.exit(0) (if it is needed)?
/*global Promise, getData, httpReq, searchData, getHotData, storeData*/
var http = require('http');
var CoubVideo = require('./models/coubdb.js');
function CoubApi (url, numPerPage, numOfPages) {
this.url = url;
this.numOfPages = numOfPages;
this.numPerPage = numPerPage;
this.getData = getData;
this.httpReq = httpReq;
this.searchData = searchData;
this.getHotData = getHotData;
this.storeData = storeData;
}
// Get data from server
function httpReq (url) {
var promise = new Promise (function (resolve, reject) {
http.get(url, function (res) {
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
if(data.length > 0) {
resolve(JSON.parse(data));
} else {
reject("Error: HTTP request rejected!");
}
});
}).on('error', function (err) {
console.log(err);
});
});
return promise;
}
// Store data in MongoDB
function storeData (data, per_page) {
function insertVideoDoc (i) {
CoubVideo.count({id: data.coubs[i].id}, function (err, count) {
if (err) {
console.log(err);
}
if (count === 0 || count === null) {
var video = new CoubVideo(data.coubs[i]);
video.save(function (err) {
if (err) {
console.log(err);
}
console.log("Saved successfully!");
});
} else {
console.log("Duplicate");
}
});
}
var i;
for(i = 0; i < per_page; i++) {
insertVideoDoc(i);
}
}
// Search for coubs
function searchData (searchtext, order, page, per_page) {
var url = this.url +
"search?q=" + searchtext +
"&order_by=" + order +
"&per_page=" + per_page +
"&page=" + page;
this.httpReq(url).then(function (data) {
this.storeData(data, per_page);
}.bind(this));
}
// Get hot coubs
function getHotData (order, page, per_page) {
var url = this.url +
"timeline/hot?page=" + page +
"&per_page=" + per_page +
"&order_by=" + order;
this.httpReq(url).then(function (data) {
this.storeData(data, per_page);
}.bind(this));
}
// Get data
function getData () {
var i;
for(i = 0; i < this.numOfPages; i++) {
this.getHotData("newest_popular", i, this.numPerPage);
}
}
var coub = new CoubApi("http://coub.com/api/v2/", 2, 50);
coub.getData();

Javascript for loop wait for callback

I have this function:
function tryStartLocalTrendsFetch(woeid) {
var userIds = Object.keys(twitClientsMap);
var isStarted = false;
for (var i = 0; i < userIds.length; i++) {
var userId = userIds[i];
var twitClientData = twitClientsMap[userId];
var isWoeidMatch = (woeid === twitClientData.woeid);
if (isWoeidMatch) {
startLocalTrendsFetch(woeid, twitClientData, function (err, data) {
if (err) {
// Couldn't start local trends fetch for userId: and woeid:
isStarted = false;
} else {
isStarted = true;
}
});
// This will not obviously work because startLocalTrendsFetch method is async and will execute immediately
if (isStarted) {
break;
}
}
}
console.log("No users are fetching woeid: " + woeid);
}
The gist of this method is that I want the line if (isStarted) { break; } to work. The reason is that if it's started it should not continue the loop and try to start another one.
I'm doing this in NodeJS.
try to use a recursive definition instead
function tryStartLocalTrendsFetch(woeid) {
var userIds = Object.keys(twitClientsMap);
recursiveDefinition (userIds, woeid);
}
function recursiveDefinition (userIds, woeid, userIndex)
var userId = userIds[userIndex = userIndex || 0];
var twitClientData = twitClientsMap[userId];
var isWoeidMatch = (woeid === twitClientData.woeid);
if (isWoeidMatch && userIndex<userIds.length) {
startLocalTrendsFetch(woeid, twitClientData, function (err, data) {
if (err) {
recursiveDefinition(userIds, woeid, userIndex + 1)
} else {
console.log("No users are fetching woeid: " + woeid);
}
});
} else {
console.log("No users are fetching woeid: " + woeid);
}
}
You may also use async (npm install async):
var async = require('async');
async.forEach(row, function(col, callback){
// Do your magic here
callback(); // indicates the end of loop - exit out of loop
}, function(err){
if(err) throw err;
});
More material to help you out: Node.js - Using the async lib - async.foreach with object

Categories

Resources