how to resolve values in nodejs promises - node.js

I am new to promises Q node module.
How to resolve values for promise object.
Here is my example:
function fs_readFile (file, encoding) {
var deferred = Q.defer()
fs.readFile(file, encoding, function (err, data) {
if (err)
deferred.reject(err)
else
deferred.resolve(data)
})
return deferred.promise
}
Now i am calling the function:
var promise=fs_readFile('myfile.txt').then(console.log, console.error);
Now i can get my file content data from then fulfill call back function but how can i get my file content data from returned promises object. like synchronously .
can any one help me!!

Promises help by encapsulating the result of an asynchronous operation but because the operation hasn't finished yet you can't actually get the result synchronously. You can get some of the appearance of synchronous behaviour though. You get the concept of functions taking arguments and returning a value. You also get error handling that climbs the stack in the same way that errors would in synchronous code.
In ES6 (the next version of JavaScript, partially supported by some of the newest browsers) you also get generators which helps you write even more synchronous seeming code.
Consider your readFile operation, if it were synchronous you could write something like:
function readJsonSync(filename) {
return JSON.parse(fs.readFileSync(filename, 'utf8'));
}
with the promise returning version in the current version of JavaScript you could write
function readJson(filename) {
return fs_readFile(filename, 'utf8').then(JSON.parse);
}
If you wanted to do the same with callbacks rathe than promises you'd have to write the following to get proper error handling behaviour:
function readJsonCallback(filename, callback){
fs.readFile(filename, 'utf8', function (err, res){
if (err) return callback(err)
try {
res = JSON.parse(res)
} catch (ex) {
return callback(ex)
}
callback(null, res)
})
}
With ES6 you can write:
var readJson = Q.async(function* (filename){
return JSON.parse(yield fs_readFile(filename, 'utf8'))
})
The yield "awaits" the promise and gives you the resolution value. The caveat is that the function that contains yield must be wrapped in Q.async and will return a promise itself.
If you want a more in depth look at this, or simply prefer videos to text, I gave a talk on this topic that you can find on YouTube: http://youtu.be/qbKWsbJ76-s

function fs_readFile (file, encoding) {
var deferred = Q.defer()
fs.readFile(file, encoding, function (err, data) {
if (err)
deferred.reject(err)
else
deferred.resolve(data)
})
return deferred.promise.then(console.log, console.error)
}
var promise=fs_readFile('myfile.txt','utf-8')

Related

Return a object from fs.readFile in Nodejs

I am trying to return jsonObj below and it is not returning. Help would be appreciated. Here fileName is the path of the file which I need to read. And again, I need to return jsonObj. So I can access it outside fs.readFile function.``
Here is the code
return fs.readFile(fileName, 'utf-8', (err, fileContent) => {
if(err) {
console.log(err); // Do something to handle the error or just throw it
throw new Error(err);
}
let jsonObj = csvjson.toObject(fileContent);
console.log(jsonObj)
return jsonObj
});
In Node you don't return from a callback function, that gets discarded and ignored. You must either use Promises, possibly in conjunction with async/await, or you must accept a callback function of your own.
This is the founding principle of asynchronous code:
// The fs.readFile() function executes immediately
fs.readFile(..., (err, ...) => {
// This code runs in the distant future, like imagine ten years from now
// from the perspective of the computer.
});
// JavaScript continues here immediately.
The readFile function does not return anything in particular, the inner function has not yet been run. It's also worth noting that throwing exceptions in there is pointless, don't do it.
To chain:
function getData(fileName, cb) {
fs.readFileName(fileName, 'utf-8', (err, fileContent) => {
if (err) {
// Back-propagate the error
return cb(err);
}
// Engage the callback function with the data
cb(null, csvjson.toObject(fileContent));
}
}
Note that this code is a lot less convoluted and messy if you use promises instead.

difference between Callback function and Promise and Async awit

I Understand Callback Function but I cant understand promise method and async and await.why to use this three function in node js.can give explain for example code.
Callback
Callback is a function that is passed as an argument to another function, and it is executed at the end. Like this:
function(callback){
//you do some tasks here that takes time
callback();
}
The callback is a method to deal with asynchronous code. For example, You may need to read a data form a file in your node app, and this process takes time. So, instead of blocking your code while reading, nodejs execute other tasks and then return back after the callback is executed.
Promise
The promise is also to deal with asynchronous code like callback method does but with more readable way. For example, instead of this:
example(function(){
return example1(function(){
return example2(function(){
return example3(function(){
done()
})
})
})
})
It makes it more readable like this:
example()
.then(example1)
.then(example2)
.then(example3)
.then(done)
Async function / Await
The async function is used to write asynchronous code, specifically promises. inside of this function the keyword await is used to pause the execution of a promise until it is resolved. In other words, it waits for the promise to resolve and then resume the async function. For example:
async function example(){
var data = await getData() // it waits until the promise is resolved
return data;
}
Callback Function
var fs = require('fs');
fs.readFile(fileName, 'utf8', function read(err, contents) {
console.log(contents);
});
console.log('after calling readFile');
Here function read(err, contents){} is a callback function and prints the contents when finished with reading the file.
But the problem in some cases might be is "after calling readFile" gets displayed to console before reading the file.
As Node Js executes statement in asynchronous mode.
Promise
var fs = require('fs');
function readMyFile(fileName)
{
return new Promise(function(resolve,reject)
{
fs.readFile(fileName, 'utf8', function read(err, contents) {
if(err)
reject(err)
else
resolve(contents)
});
}
}
var file = readMyFile(fileName).then(result=>{console.log(result);console.log('after calling readFile'); }).catch(err=>{console.log("Error Occurred",err)});
console.log(file);
Here function readMyFile(fileName) is a function that returns promise prints the contents in then block and displays an error in the catch block.
But here the line console.log(file); gets executed without waiting for the file variable being defined
Async/Await
var fs = require('fs');
function readMyFile(fileName)
{
return new Promise(function(resolve,reject)
{
fs.readFile(fileName, 'utf8', function read(err, contents) {
if(err)
reject(err)
else
resolve(contents)
});
}
}
async function read()
{
var file = await readMyFile(fileName);
console.log(file);
}
Here await hold the line until file variable gets its value
await works only with the promise
await can only be used inside async functions

NodeJS Express Async issue

I have this function which gets some data from my database but i'm having a trouble calling the function and getting the proper response
function getEvents()
{
var x = [];
var l = dbCollection['e'].find({}).forEach(function(y) {
x.push(y);
});
return x;
});
and another function which calls this function but it always returns undefined.
How can i make the function wait till mongoose has finished filling up the array?
Thanks for the help! My life
dbCollection['e'].find is called non-blocking way so you are returning x before filling. You need to use callbacks or some mongoose promises. You can get all returning values from database like following snippet
function getEvents(callback) {
dbCollection['e'].find({}, function(error, results) {
// results is array.
// if you need to filter results you can do it here
return callback(error, results);
})
}
Whenever you need to call getEvents function you need to pass a callback to it.
getEvents(function(error, results) {
console.log(results); // you have results here
})
You should read mongoose docs for how queries work.
There is also support for promises in mongoose. You can check this url for more information about promises.
The solution proposed by #orhankutlu should work fine.
I will give another solution using promise. You can choose one between these two solutions depending on your style of programming.
Solution using promise:
function getEvents() {
return new Promise(function(resolve, reject){
dbCollection['e'].find({}, function(error, results) {
if (error) return reject(error);
var x = [];
results.forEach(function(y){
x.push(y);
});
// forEach() is a blocking call,
// so the promise will be resolved only
// after the forEach completes
return resolve(x);
});
});
};
Calling getEvents():
getEvents().then(function(result){
console.log(result); //should print 'x'
}).catch(function(err){
// Handle error here in case the promise is rejected
});
I will encourage you to try both the approaches, ie, using callbacks and using promises. Hope you find it useful!

How exactly does a callback function work in nodejs?

I went through many examples of nodejs with callbacks, but didn't understand how exactly they work. I know that they're executed after the function, of which they're a part of is done, but I didn't understand callbacks as a function. Let me give an example:
function processData (callback) {
fetchData(function (err, data) {
if (err) {
console.log("An error has occured. Abort everything!");
callback(err);
}
data += 1;
callback(data);
});
}
Here, what how do callback(err) and callback(data) execute, as in, is it an alias for some other function to which we're passing the parameters - err/ data? If so, which function does it call when we write callback(parameter)?
Here's another example :
var express = require("express");
var bodyParser = require("body-parser");
var multer = require('multer');
var app = express();
app.use(bodyParser.json());
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage }).array('userPhoto',2);
app.get('/',function(req,res){
res.sendFile(__dirname + "/index.html");
});
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
//console.log(req.body);
//console.log(req.files);
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
app.listen(3000,function(){
console.log("Working on port 3000");
});
Again I sort of understood the other type of callback - suppose, here fs.readdir
fs.readdir(path, function (err, files) {
if (err) console.error(err);
for (var i = 0; i<files.length; i++) console.log(files[i];
}
console.log("done");
I know how this executes, most probably it'll print done first, and then prints the list of files, as soon as readdir is executed with files having the list of files.
But I didn't exactly understand the first and second code snippet. Can someone please explain that in simple terms, specific to the multer code snippet?
Callbacks and asynchronous behaviour are two different but related things. They're relate in the sense that asynchronous code can use callback to execute code in the intended sequence. But callbacks by themselves are just the result of the language treating functions as objects.
In your examples, you can see two sides of the callback story. One is the implementation and the other is the usage. The first code is an example of how to implement a function that accepts a callback. The last is an example of how to use a function that accepts a callback.
For simplicity let's ignore asynchronous behaviour for now and implement synchronous callbacks.
The following is an example of a function that loops through an array to construct a string:
function joiner (arr, callback) {
var return_value = "";
for (var i=0; i<arr.length; i++) {
return_value += callback(arr[i]); // use callback on each item
}
return return_value;
}
Once we've implemented the function above we can use it:
var result = joiner(['this','is','cool'],function(x) {
return "--> " + x + "!";
});
So, how do we know what arguments the callback accept? It accepts what the caller passes to it.
How do we know what arguments to pass to a callback function? We pass what the function is defined to accept?
If that sounds circular, it is. So how we really know what arguments to pass to a callback is:
If it's an API we created, we can do anything we want
If it's an API someone else created, read the documentation (or if your IDE can do it, check out the intellisense)
Callbacks gone meta
The above explanation is of course only the simplest example of callbacks: functions that accept a callback. The express example (and indeed your first example) shows how you can get even more complicated. You can write functions that accept a callback that accept a callback.
A simplified example of functions that accept a callback that accept a callback is something like this:
function processData (data) {
return "<" + data + ">";
}
function render (callback) {
return callback(processData);
}
So the render function above accepts a callback that will be passed a callback that returns a string. So if we now do:
var result = render(function(callback){
return "--" + callback('hello');
});
we will get:
--<hello>
As you can see, the callback we passed to render does not know how to process the data but render does (it calls processData). And render does not know what the data is but the callback we passed to it does ('hello'). Being able to pass a callback to a callback allows two pieces of code to cooperate without exposing each other's implementation details.
Async code uses this technique to order the sequence of code being executed. Because async code cannot return a value you can only pass it a callback so that once it gets its value your code (callback) can continue.
If you think about it, the Express API could have easily been implemented so that request handler callbacks must return the HTML page instead of calling res.send(). Indeed, this is how frameworks work in many languages. But that means that the request handler cannot execute asynchronous code to fetch data. Because Express doesn't want to limit you to using only synchronous code it passes an object with callback methods instead (res). This "design pattern" is called a monad. The one you see in Express is a continuation monad while the one you see in fs.readdir() is an I/O monad.
First, you got confused because you're not following the Node JS standards for passing parameters to asynchronous function. Every async callback must take 2 parameters. First should always be error and 2nd should always be data. Refer to how the callbacks for readdir and fetchData are defined.
So your code should ideally look like
function processData (callback) {
fetchData(function (err, data) {
if (err) {
console.log("An error has occured. Abort everything!");
callback(err, null); // here data will be null
}
data += 1;
callback(null, data); // here err will be null.
});
}
And you will define your callback function for processData at the time you call it like
processData(function(err, data){
err ? console.error(err) : console.log(data);
});
This way, in your callback, you know for sure whether the function has succeeded or failed.

Node.js consecutive method calls with nested callback formatting

So I'm new to Node.js and Im just wondering if the way I have my code setup makes sense. Im coming from a Java background so the nested callback structure is new. I have a Node program that runs a bunch of code that I broke down into different methods. The thing is that the methods need to be called in order. My code has this structure right now:
functionOne(data, callback(err) {
functionTwo(data, callback(err) {
functionThree(data, callback(err) {
functionFour(data, callback(err) {
//Code
});
});
});
});
This is very minimalistic, but is this structure ok? With Java, I'd take the return values of all the methods, then just pass them to the next function. From my understanding so far, the Java approach I just mentioned is one of the main things that Node.js was trying to eliminate. But anyway... Does that structure look ok, and is that how its intended to look? Just want to be sure that I'm not making any major errors with Node in general. Thanks!
Your code structure looks fine if you work with callback pattern.
But if you're interested in make your code cleaner and readable you would like to use Promises in your asynchronous function, so instead of pass a callback to your functions you could do something like this :
function asyncFunction (data){
return new Promise(function(resolve, reject){
// Do something with data
// Here you can call reject(error) to throw an error
resolve();
});
}
And instead of nested function callbacks you can call then method of Promise.
asyncFunction(data)
.then(function(){
// Promise resolved
// Something has been done with data
});
With Promises you can also execute async fuctions in parallel :
Promise.all([asyncFunctionA(data), asyncFunctionB(data), asyncFunctionC(data)])
.then(function(){...});
EDIT
If you need to pass values of one function to another, your code should look like this :
asyncFunctionA(data)
.then(function(dataA){
return asyncFunctionB(dataA);
})
.then(function(dataB){
return asyncFunctionC(dataB);
})
.then(function(dataC){
// ...
});
You should try to use promises to avoid your callback hell, so it could be something like these...
const Q = require('q'); // you can do a research for this module.
var myModule = {};
myModule.functionOne = (params) => {
const deferred = Q.defer(); // wait for this to complete
// body function
deferred.resolve(data); // this would be the result of this function
return deferred.promise; // data is the output on your function
}
myModule.functionTwo = (params) => {
const deferred = Q.defer(); // wait for this to complete
// body function
deferred.resolve(data); // this would be the result of this function
return deferred.promise; // data is the output on your function
}
myModule.doAll = (params) => {
myModule.functionOne(params)
.then((outputFunctionOne) => {
// this is called after functionOne ends
return myModule.functionTwo(outputFunctionOne);
})
.then((outputFunctionTwo) => {
// this is called after function 2 ends
if (outputFunctionTwo.success) {
// if everything ok, resolve the promise with the final output
deferred.resolve(outputFunctionTwo);
} else {
// reject the promise with an error message
deferred.reject('error');
}
})
.fail((err) => {
// this is call if the promise is rejected or an exception is thrown
console.log(err); // TODO: Error handling
})
.done();
}
module.exports = myModule;
You can Chain as many promises as you want really easily, that way you get rid of the callback hell. Best part, you can do promises on Javascript or Node.js
Reference Link https://github.com/kriskowal/q
Hope this helps
Most of the other answers give Promise/A as the answer to your callback woes. This is correct, and will work for you. However I'd like to give you another option, if you are willing to drop javascript as your working language.
Introducing Iced Coffee, a branch of the CoffeeScript project.
With Iced Coffee you would write:
await functionOne data, defer err
await functionTwo data, defer err2
await functionThree data, defer err3
//etc
This then compiles to the CoffeeScript:
functionOne data, (err) ->
functionTwo data, (err2) ->
functionThree data, (err3) ->
//etc
Which then compiles to your Javascript.
functionOne(data, callback(err) {
functionTwo(data, callback(err2) {
functionThree(data, callback(err3) {
//etc
});
});
});

Resources