The simple solution is to just put the rest of your code that you want to execute after the fs.readFile()
operation into a function and then insert that function into the async callback:
var fs = require('fs');
console.log("1");
fs.readFile("./index.js", function(err, data) {
if (err) {
console.log("err");
}
console.log("2");
moreCode();
});
function moreCode() {
console.log("3");
}
A bit more modern design is to use promises for all your asynchronous operations and then you can sequence things a bit easier.
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
console.log("1");
fs.readFileAsync("./index.js").then((data) => {
console.log("2");
return moreCode();
}).catch((err) => {
// handle error here
});
function moreCode() {
console.log("3");
}
Where the benefit of using promises really starts to take advantage is when you have multiple asynchronous operations that you want to sequence and each one returns a promise. Then, you can do that like this:
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
fs.readFileAsync("./index.js")
.then(moreCode1)
.then(moreCode2)
.catch((err) => {
// handle error here
});
Using the code you've show for the urlex()
function, here's how you can make all that work using promises:
// include infrastructure to automatically promisify the fs module
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
function servedatastart() {
Promise.resolve().then(function() {
if (urlcontentbasic(urlslug) != "err") {
// I'm assuming that urlcontentbasic is also async and returns a promise
// like urlexbasic does
return urlcontentbasic(urlslug);
} else {
// callback function
console.log("urlex");
return urlex("none", urlslug);
}
}).then(function() {
console.log("other function");
//other function
cuswriteheader();
includescript();
writefooter()
res.end();
});
}
// basic function for reading extension-less URL
// returns a promise whose resolved value is a returnarray data structure
function urlexbasic(filetype, slug) {
var returnarray = {status:null,contenttype:null,data:null,message:undefined};
if (slug == undefined) {
slug = "";
}
if (filetype == "none") {
var filename;
console.log("path: "+pathdataarray["1"]);
if (pathdataarray["1"] == "/pre") {
console.log("substr");
filename = urlslug.substr(4, urlslug.length-5);
console.log("1: "+filename);
}
urldata(q.pathname, "");
console.log("slug: "+ slug+" filename: "+ filename);
if (slug != "" || filename != undefined) {
console.log("what?")
if (filename != undefined) {
filename = "." + filename;
} else {
filename = "." + slug;
}
console.log("2: "+filename);
} else {
filename = "." + urlslug.substr(0, urlslug.length-1);
}
console.log("filename: "+ filename);
return fs.readFileAsync(filename.substr(0, filename.length-1), 'utf8').then(function(data) {
console.log("readfile");
var mime = null;
if (urldataarray.extension == "js") {
mime = "javascript";
} else {
mime = urldataarray.extension;
}
console.log("hey running");
returnarray["status"] = 200;
returnarray["contenttype"] = 'text/'+mime;
//res.writeHead(200, {'contenttype': 'text/'+mime});
returnarray["data"] = data;
console.log("instatus: "+returnarray["status"]);
// make returnarray be the resolved value of the promise
return returnarray;
}).catch(function(err) {
console.log("404 error");
returnarray["status"] = 404;
});
} else {
urldata(q.pathname, filetype);
var filename;
if (pathdataarray["1"] == "/pre") {
console.log("substr");
filename = urlslug.substr(4, urlslug.length-5);
console.log("11: "+filename);
}
console.log("2slug: "+ slug+" filename: "+ filename);
if (slug != "" || filename != undefined) {
if (filename) {
filename = "." + filename + "." + filetype;
} else {
filename = "." + slug +"."+ filetype;
}
console.log("22: "+filename);
} else {
filename = "." + urlslug.substr(0, urlslug.length-1) + "." + filetype;
}
return fs.readFileAsync(filename, 'utf8').then(function(data) {
var mime = null;
if (urldataarray.extension == "js") {
mime = "javascript";
} else {
mime = urldataarray.extension;
console.log("ok");
};
if (pathdataarray["1"] == "/pre") {
returnarray["status"] = 200;
returnarray["contenttype"] = 'text/plain';
//res.writeHead(200, {'contenttype': 'text/plain'});
//res.write("<pre><code>");
returnarray["data"] = data;
//res.write("</code></pre>");
} else {
returnarray["status"] = 200;
returnarray["contenttype"] = 'text/'+mime;
//res.writeHead(200, {'contenttype': 'text/'+mime});
console.log("pure data");
returnarray["data"] = data;
}
// make returnarray be the resolved value of the promise
return returnArray;
}).catch(function(err) {
return urlex(dataerrcall[filetype]);
});
}
}
// returns a promise whose resolved value is a returnArray
function urlex(filetypeex, slugex) {
//console.log(urlexbasic(filetypeex, slugex));
return urlexbasic(filetypeex, slugex).then(function(returnArray) {
console.log("return: "+returnarray.status);
responsearray["status"] = returnarray["status"];
responsearray["contenttype"] = returnarray["contenttype"]
responsearray["message"] = returnarray["message"];
responsearray["data"] = returnarray["data"];
return responsearray;
});
}
This uses several nice promise features such as chaining (to sequence async operations).