Is it necessary to reject a deferred promise in Angular? [duplicate] - angularjs

I was writing code that does something that looks like:
function getStuffDone(param) { | function getStuffDone(param) {
var d = Q.defer(); /* or $q.defer */ | return new Promise(function(resolve, reject) {
// or = new $.Deferred() etc. | // using a promise constructor
myPromiseFn(param+1) | myPromiseFn(param+1)
.then(function(val) { /* or .done */ | .then(function(val) {
d.resolve(val); | resolve(val);
}).catch(function(err) { /* .fail */ | }).catch(function(err) {
d.reject(err); | reject(err);
}); | });
return d.promise; /* or promise() */ | });
} | }
Someone told me this is called the "deferred antipattern" or the "Promise constructor antipattern" respectively, what's bad about this code and why is this called an antipattern?

The deferred antipattern (now explicit-construction anti-pattern) coined by Esailija is a common anti-pattern people who are new to promises make, I've made it myself when I first used promises. The problem with the above code is that is fails to utilize the fact that promises chain.
Promises can chain with .then and you can return promises directly. Your code in getStuffDone can be rewritten as:
function getStuffDone(param){
return myPromiseFn(param+1); // much nicer, right?
}
Promises are all about making asynchronous code more readable and behave like synchronous code without hiding that fact. Promises represent an abstraction over a value of one time operation, they abstract the notion of a statement or expression in a programming language.
You should only use deferred objects when you are converting an API to promises and can't do it automatically, or when you're writing aggregation functions that are easier expressed this way.
Quoting Esailija:
This is the most common anti-pattern. It is easy to fall into this when you don't really understand promises and think of them as glorified event emitters or callback utility. Let's recap: promises are about making asynchronous code retain most of the lost properties of synchronous code such as flat indentation and one exception channel.

What's wrong with it?
But the pattern works!
Lucky you. Unfortunately, it probably doesn't, as you likely forgot some edge case. In more than half of the occurrences I've seen, the author has forgotten to take care of the error handler:
return new Promise(function(resolve) {
getOtherPromise().then(function(result) {
resolve(result.property.example);
});
})
If the other promise is rejected, this will happen unnoticed instead of being propagated to the new promise (where it would get handled) - and the new promise stays forever pending, which can induce leaks.
The same thing happens in the case that your callback code causes an error - e.g. when result doesn't have a property and an exception is thrown. That would go unhandled and leave the new promise unresolved.
In contrast, using .then() does automatically take care of both these scenarios, and rejects the new promise when an error happens:
return getOtherPromise().then(function(result) {
return result.property.example;
})
The deferred antipattern is not only cumbersome, but also error-prone. Using .then() for chaining is much safer.
But I've handled everything!
Really? Good. However, this will be pretty detailed and copious, especially if you use a promise library that supports other features like cancellation or message passing. Or maybe it will in the future, or you want to swap your library against a better one? You won't want to rewrite your code for that.
The libraries' methods (then) do not only natively support all the features, they also might have certain optimisations in place. Using them will likely make your code faster, or at least allow to be optimised by future revisions of the library.
How do I avoid it?
So whenever you find yourself manually creating a Promise or Deferred and already existing promises are involved, check the library API first. The Deferred antipattern is often applied by people who see promises [only] as an observer pattern - but promises are more than callbacks: they are supposed to be composable. Every decent library has lots of easy-to-use functions for the composition of promises in every thinkable manner, taking care of all the low-level stuff you don't want to deal with.
If you have found a need to compose some promises in a new way that is not supported by an existing helper function, writing your own function with unavoidable Deferreds should be your last option. Consider switching to a more featureful library, and/or file a bug against your current library. Its maintainer should be able to derive the composition from existing functions, implement a new helper function for you and/or help to identify the edge cases that need to be handled.

Now 7 years later there is a simpler answer to this question:
How do I avoid the explicit constructor antipattern?
Use async functions, then await every Promise!
Instead of manually constructing nested Promise chains such as this one:
function promised() {
return new Promise(function(resolve) {
getOtherPromise().then(function(result) {
getAnotherPromise(result).then(function(result2) {
resolve(result2);
});
});
});
}
just turn your function async and use the await keyword to stop execution of the function until the Promise resolves:
async function promised() {
const result = await getOtherPromise();
const result2 = await getAnotherPromise(result);
return result2;
}
This has various benefits:
Calling the async function always returns a Promise, which resolves with the returned value and rejects if an error get's thrown inside the async function
If an awaited Promise rejects, the error get's thrown inside the async function, so you can just try { ... } catch(error) { ... } it like the synchronous errors.
You can await inside loops and if branches, making most of the Promise chain logic trivial
Although async functions behave mostly like chains of Promises, they are way easier to read (and easier to reason about)
How can I await a callback?
If the callback only calls back once, and the API you are calling does not provide a Promise already (most of them do!) this is the only reason to use a Promise constructor:
// Create a wrapper around the "old" function taking a callback, passing the 'resolve' function as callback
const delay = time => new Promise((resolve, reject) =>
setTimeout(resolve, time)
);
await delay(1000);
If await stops execution, does calling an async function return the result directly?
No. If you call an async function, a Promise gets always returned. You can then await that Promise too inside an async function. You cannot wait for the result inside of a synchronous function (you would have to call .then and attach a callback).
Conceptually, synchronous functions always run to completion in one job, while async functions run synchronously till they reach an await, then they continue in another job.

Related

Are async useEffect Callbacks Actually Harmful, or Just a "Smell"?

I can find lots of articles on the web that will tell you to change:
useEffect(async() => {
await doSomethingAsynchronous();
})
into:
useEffect(() => {
const pointlessFunction = async () => {
await doSomethingAsynchronous();
};
pointlessFunction();
})
But what I can't find is any explanation of the actual harm caused by the former.
I understand that React's ESLint rules will complain if you do the former, and I understand that it's complaining because the former might confusingly suggest that useEffect is waiting for the AJAX to complete (when it's not).
In both cases the async function is generating a promise, and in both cases that promise is being ignored (meaning that neither version is actually waiting for doSomethingAsynchronous to complete).
But ... if you understand the above, and can still write working code in spite of it ... is there any actual harm to doing the former?
EDIT:
It seems from the answers so far there is some "harm", but it's only in the form of limiting options. If I go with form #2, I can't:
return a cleanup function (because the async will make the function always return a promise)
wrap the callback with a try/catch
So maybe that's the only harm: form #1 can't error handle or do cleanup. But I'm still curious: aside from limiting my options, if I don't need to cleanup or handle errors, will form #1 actually break anything (ie. cause harm)?
After all, using a one-line arrow function (() => 5) limits your options too ... but we still use them all the time, and just use the more verbose form when we need it. Why not do the same here?
There are a couple of issues.
React expects two possible return values from the callback: nothing (in which case there is no cleanup function to run), or a function (in which case that function is the cleanup function that will be run). If you return something other than those two return values, you're doing something that React doesn't know how to handle - which means that the logic you're implementing may well be buggy - the script-writer is returning a value of an unexpected type, and may be expecting React to do something with it - but it won't.
It's a bit like doing
someArray.forEach((item) => {
// do something
return true;
});
Because forEach ignores the value returned from the callback, any time you see code like this, it's probably a bug (or useless). If some library-writer nowadays decided to implement forEach themselves they might decide to be strict and show a warning when it sees a value returned from the callback.
React is doing something similar. Using an async function (or returning a non-undefined, non-function value) isn't inherently absolutely forbidden and so doesn't produce an error, but it does indicate that there's something wrong, so it produces a warning.
Async functions that reject will result in unhandled rejections, which should absolutely be avoided for the same reason that plain runtime errors should be avoided. If you had
useEffect(async() => {
await doSomethingAsynchronous();
})
and doSomethingAsynchronous rejected, you would end up with an unhandled rejection - because React does not do anything with the returned Promise, and you should implement the error handling yourself.
While the other answers here are great and informative, none directly answered my original question, ie. "Is there any harm to providing useEffect with an async callback?
The answer is ... no, there is no harm.
However, there is an important limitation to that approach, which is that you cannot provide a cleanup function if you use it (because async functions can never return functions, only promises). Also, some devs may be concerned that future versions of React may break when an async callback is given to useEffect.
Both concerns can easily be addressed with a wrapper around useEffect, called something like useAsyncEffect. This allows you to avoid ES Lint issues (and ensure compatibility with future React versions), while still providing a cleanup function.
export const useAsyncEffect = (effect, dependencies, cleanup) => {
// If no dependencies are provided but a cleanup function is, fix args
if (!cleanup && typeof dependencies === 'function') {
cleanup = dependencies;
dependencies = undefined;
}
// Main wrapper code
useEffect(() => {
effect();
return cleanup;
}, dependencies);
};
I think that it is a bad practice to use async functions in use effects because:
The useEffect function expects to receive a function that returns another function to execute once your component is unmounted, rather than a promise.
As far as I know, non-handled async functions may cause some issues with states when your component is re-rendered, but your async function is not completed yet.

How to use .finally() without .then()?

I want a block of code to run after every resolution/rejection of a promise (using $q in AngularJS 1.6.x).
I know I can do:
myPromise()
.then((response) => {
// Do my important stuff here
})
.catch((response) => {
// Copy code from above
})
As well as this (slightly better):
myPromise()
.catch(() => {})
.then((response) => {
// Do my important stuff here, and only write it once
})
But I just want to write something like:
myPromise()
.finally((response) => {
// Do my important stuff here, only written once
})
But it seems .finally() will not run without a then() or catch() block handling the resolution/rejection first.
Any way to do this?
You can do this, but the question is why? rather than how?
.finally() in fact will run even if there is no .then() or .catch() preceding it. But it's an antipattern to do so because you're avoiding handling errors that could prevent your code from running.
Additionally, since .finally() does not expose a response or provide a new promise, it is inferior to the other two in utility. The truth is that .finally() only serves the limited cases it's meant for -- to run code that should execute regardless of the fate of the promise, such as cleaning up variables that are set to indicate to the rest of the application that the promise hasn't yet returned, for instance.
So it's not a completely meaningless question, but it's not a realistic scenario to be concerned about -- where you would want to run .finally() without a .then() or .catch().

reactjs: cannot access state data through async/await/promise function [duplicate]

Given the following examples, why is outerScopeVar undefined in all cases?
var outerScopeVar;
var img = document.createElement('img');
img.onload = function() {
outerScopeVar = this.width;
};
img.src = 'lolcat.png';
alert(outerScopeVar);
var outerScopeVar;
setTimeout(function() {
outerScopeVar = 'Hello Asynchronous World!';
}, 0);
alert(outerScopeVar);
// Example using some jQuery
var outerScopeVar;
$.post('loldog', function(response) {
outerScopeVar = response;
});
alert(outerScopeVar);
// Node.js example
var outerScopeVar;
fs.readFile('./catdog.html', function(err, data) {
outerScopeVar = data;
});
console.log(outerScopeVar);
// with promises
var outerScopeVar;
myPromise.then(function (response) {
outerScopeVar = response;
});
console.log(outerScopeVar);
// with observables
var outerScopeVar;
myObservable.subscribe(function (value) {
outerScopeVar = value;
});
console.log(outerScopeVar);
// geolocation API
var outerScopeVar;
navigator.geolocation.getCurrentPosition(function (pos) {
outerScopeVar = pos;
});
console.log(outerScopeVar);
Why does it output undefined in all of these examples? I don't want workarounds, I want to know why this is happening.
Note: This is a canonical question for JavaScript asynchronicity. Feel free to improve this question and add more simplified examples which the community can identify with.
One word answer: asynchronicity.
Forewords
This topic has been iterated at least a couple of thousands of times here in Stack Overflow. Hence, first off I'd like to point out some extremely useful resources:
#Felix Kling's answer to "How do I return the response from an asynchronous call?". See his excellent answer explaining synchronous and asynchronous flows, as well as the "Restructure code" section.
#Benjamin Gruenbaum has also put a lot of effort into explaining asynchronicity in the same thread.
#Matt Esch's answer to "Get data from fs.readFile" also explains asynchronicity extremely well in a simple manner.
The answer to the question at hand
Let's trace the common behavior first. In all examples, the outerScopeVar is modified inside of a function. That function is clearly not executed immediately; it is being assigned or passed as an argument. That is what we call a callback.
Now the question is, when is that callback called?
It depends on the case. Let's try to trace some common behavior again:
img.onload may be called sometime in the future when (and if) the image has successfully loaded.
setTimeout may be called sometime in the future after the delay has expired and the timeout hasn't been canceled by clearTimeout. Note: even when using 0 as delay, all browsers have a minimum timeout delay cap (specified to be 4ms in the HTML5 spec).
jQuery $.post's callback may be called sometime in the future when (and if) the Ajax request has been completed successfully.
Node.js's fs.readFile may be called sometime in the future when the file has been read successfully or thrown an error.
In all cases, we have a callback that may run sometime in the future. This "sometime in the future" is what we refer to as asynchronous flow.
Asynchronous execution is pushed out of the synchronous flow. That is, the asynchronous code will never execute while the synchronous code stack is executing. This is the meaning of JavaScript being single-threaded.
More specifically, when the JS engine is idle -- not executing a stack of (a)synchronous code -- it will poll for events that may have triggered asynchronous callbacks (e.g. expired timeout, received network response) and execute them one after another. This is regarded as Event Loop.
That is, the asynchronous code highlighted in the hand-drawn red shapes may execute only after all the remaining synchronous code in their respective code blocks have executed:
In short, the callback functions are created synchronously but executed asynchronously. You can't rely on the execution of an asynchronous function until you know it has been executed, and how to do that?
It is simple, really. The logic that depends on the asynchronous function execution should be started/called from inside this asynchronous function. For example, moving the alerts and console.logs inside the callback function would output the expected result because the result is available at that point.
Implementing your own callback logic
Often you need to do more things with the result from an asynchronous function or do different things with the result depending on where the asynchronous function has been called. Let's tackle a bit more complex example:
var outerScopeVar;
helloCatAsync();
alert(outerScopeVar);
function helloCatAsync() {
setTimeout(function() {
outerScopeVar = 'Nya';
}, Math.random() * 2000);
}
Note: I'm using setTimeout with a random delay as a generic asynchronous function; the same example applies to Ajax, readFile, onload, and any other asynchronous flow.
This example clearly suffers from the same issue as the other examples; it is not waiting until the asynchronous function executes.
Let's tackle it by implementing a callback system of our own. First off, we get rid of that ugly outerScopeVar which is completely useless in this case. Then we add a parameter that accepts a function argument, our callback. When the asynchronous operation finishes, we call this callback, passing the result. The implementation (please read the comments in order):
// 1. Call helloCatAsync passing a callback function,
// which will be called receiving the result from the async operation
helloCatAsync(function(result) {
// 5. Received the result from the async function,
// now do whatever you want with it:
alert(result);
});
// 2. The "callback" parameter is a reference to the function which
// was passed as an argument from the helloCatAsync call
function helloCatAsync(callback) {
// 3. Start async operation:
setTimeout(function() {
// 4. Finished async operation,
// call the callback, passing the result as an argument
callback('Nya');
}, Math.random() * 2000);
}
Code snippet of the above example:
// 1. Call helloCatAsync passing a callback function,
// which will be called receiving the result from the async operation
console.log("1. function called...")
helloCatAsync(function(result) {
// 5. Received the result from the async function,
// now do whatever you want with it:
console.log("5. result is: ", result);
});
// 2. The "callback" parameter is a reference to the function which
// was passed as an argument from the helloCatAsync call
function helloCatAsync(callback) {
console.log("2. callback here is the function passed as argument above...")
// 3. Start async operation:
setTimeout(function() {
console.log("3. start async operation...")
console.log("4. finished async operation, calling the callback, passing the result...")
// 4. Finished async operation,
// call the callback passing the result as argument
callback('Nya');
}, Math.random() * 2000);
}
Most often in real use cases, the DOM API and most libraries already provide the callback functionality (the helloCatAsync implementation in this demonstrative example). You only need to pass the callback function and understand that it will execute out of the synchronous flow and restructure your code to accommodate for that.
You will also notice that due to the asynchronous nature, it is impossible to return a value from an asynchronous flow back to the synchronous flow where the callback was defined, as the asynchronous callbacks are executed long after the synchronous code has already finished executing.
Instead of returning a value from an asynchronous callback, you will have to make use of the callback pattern, or... Promises.
Promises
Although there are ways to keep the callback hell at bay with vanilla JS, promises are growing in popularity and are currently being standardized in ES6 (see Promise - MDN).
Promises (a.k.a. Futures) provide a more linear, and thus pleasant, reading of the asynchronous code, but explaining their entire functionality is out of the scope of this question. Instead, I'll leave these excellent resources for the interested:
JavaScript Promises - HTML5 Rocks
You're Missing the Point of Promises - domenic.me
More reading material about JavaScript asynchronicity
The Art of Node - Callbacks explains asynchronous code and callbacks very well with vanilla JS examples and Node.js code as well.
Note: I've marked this answer as Community Wiki. Hence anyone with at least 100 reputations can edit and improve it! Please feel free to improve this answer or submit a completely new answer if you'd like as well.
I want to turn this question into a canonical topic to answer asynchronicity issues that are unrelated to Ajax (there is How to return the response from an AJAX call? for that), hence this topic needs your help to be as good and helpful as possible!
Fabrício's answer is spot on; but I wanted to complement his answer with something less technical, which focusses on an analogy to help explain the concept of asynchronicity.
An Analogy...
Yesterday, the work I was doing required some information from a colleague. I rang him up; here's how the conversation went:
Me: Hi Bob, I need to know how we foo'd the bar'd last week. Jim wants a report on it, and you're the only one who knows the details about it.
Bob: Sure thing, but it'll take me around 30 minutes?
Me: That's great Bob. Give me a ring back when you've got the information!
At this point, I hung up the phone. Since I needed information from Bob to complete my report, I left the report and went for a coffee instead, then I caught up on some email. 40 minutes later (Bob is slow), Bob called back and gave me the information I needed. At this point, I resumed my work with my report, as I had all the information I needed.
Imagine if the conversation had gone like this instead;
Me: Hi Bob, I need to know how we foo'd the bar'd last week. Jim want's a report on it, and you're the only one who knows the details about it.
Bob: Sure thing, but it'll take me around 30 minutes?
Me: That's great Bob. I'll wait.
And I sat there and waited. And waited. And waited. For 40 minutes. Doing nothing but waiting. Eventually, Bob gave me the information, we hung up, and I completed my report. But I'd lost 40 minutes of productivity.
This is asynchronous vs. synchronous behavior
This is exactly what is happening in all the examples in our question. Loading an image, loading a file off disk, and requesting a page via AJAX are all slow operations (in the context of modern computing).
Rather than waiting for these slow operations to complete, JavaScript lets you register a callback function which will be executed when the slow operation has completed. In the meantime, however, JavaScript will continue to execute other code. The fact that JavaScript executes other code whilst waiting for the slow operation to complete makes the behaviorasynchronous. Had JavaScript waited around for the operation to complete before executing any other code, this would have been synchronous behavior.
var outerScopeVar;
var img = document.createElement('img');
// Here we register the callback function.
img.onload = function() {
// Code within this function will be executed once the image has loaded.
outerScopeVar = this.width;
};
// But, while the image is loading, JavaScript continues executing, and
// processes the following lines of JavaScript.
img.src = 'lolcat.png';
alert(outerScopeVar);
In the code above, we're asking JavaScript to load lolcat.png, which is a sloooow operation. The callback function will be executed once this slow operation has done, but in the meantime, JavaScript will keep processing the next lines of code; i.e. alert(outerScopeVar).
This is why we see the alert showing undefined; since the alert() is processed immediately, rather than after the image has been loaded.
In order to fix our code, all we have to do is move the alert(outerScopeVar) code into the callback function. As a consequence of this, we no longer need the outerScopeVar variable declared as a global variable.
var img = document.createElement('img');
img.onload = function() {
var localScopeVar = this.width;
alert(localScopeVar);
};
img.src = 'lolcat.png';
You'll always see a callback is specified as a function, because that's the only* way in JavaScript to define some code, but not execute it until later.
Therefore, in all of our examples, the function() { /* Do something */ } is the callback; to fix all the examples, all we have to do is move the code which needs the response of the operation into there!
* Technically you can use eval() as well, but eval() is evil for this purpose
How do I keep my caller waiting?
You might currently have some code similar to this;
function getWidthOfImage(src) {
var outerScopeVar;
var img = document.createElement('img');
img.onload = function() {
outerScopeVar = this.width;
};
img.src = src;
return outerScopeVar;
}
var width = getWidthOfImage('lolcat.png');
alert(width);
However, we now know that the return outerScopeVar happens immediately; before the onload callback function has updated the variable. This leads to getWidthOfImage() returning undefined, and undefined being alerted.
To fix this, we need to allow the function calling getWidthOfImage() to register a callback, then move the alert'ing of the width to be within that callback;
function getWidthOfImage(src, cb) {
var img = document.createElement('img');
img.onload = function() {
cb(this.width);
};
img.src = src;
}
getWidthOfImage('lolcat.png', function (width) {
alert(width);
});
... as before, note that we've been able to remove the global variables (in this case width).
Here's a more concise answer for people that are looking for a quick reference as well as some examples using promises and async/await.
Start with the naive approach (that doesn't work) for a function that calls an asynchronous method (in this case setTimeout) and returns a message:
function getMessage() {
var outerScopeVar;
setTimeout(function() {
outerScopeVar = 'Hello asynchronous world!';
}, 0);
return outerScopeVar;
}
console.log(getMessage());
undefined gets logged in this case because getMessage returns before the setTimeout callback is called and updates outerScopeVar.
The two main ways to solve it are using callbacks and promises:
Callbacks
The change here is that getMessage accepts a callback parameter that will be called to deliver the results back to the calling code once available.
function getMessage(callback) {
setTimeout(function() {
callback('Hello asynchronous world!');
}, 0);
}
getMessage(function(message) {
console.log(message);
});
Promises
Promises provide an alternative which is more flexible than callbacks because they can be naturally combined to coordinate multiple async operations. A Promises/A+ standard implementation is natively provided in node.js (0.12+) and many current browsers, but is also implemented in libraries like Bluebird and Q.
function getMessage() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('Hello asynchronous world!');
}, 0);
});
}
getMessage().then(function(message) {
console.log(message);
});
jQuery Deferreds
jQuery provides functionality that's similar to promises with its Deferreds.
function getMessage() {
var deferred = $.Deferred();
setTimeout(function() {
deferred.resolve('Hello asynchronous world!');
}, 0);
return deferred.promise();
}
getMessage().done(function(message) {
console.log(message);
});
async/await
If your JavaScript environment includes support for async and await (like Node.js 7.6+), then you can use promises synchronously within async functions:
function getMessage () {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('Hello asynchronous world!');
}, 0);
});
}
async function main() {
let message = await getMessage();
console.log(message);
}
main();
To state the obvious, the cup represents outerScopeVar.
Asynchronous functions be like...
The other answers are excellent and I just want to provide a straight forward answer to this. Just limiting to jQuery asynchronous calls
All ajax calls (including the $.get or $.post or $.ajax) are asynchronous.
Considering your example
var outerScopeVar; //line 1
$.post('loldog', function(response) { //line 2
outerScopeVar = response;
});
alert(outerScopeVar); //line 3
The code execution starts from line 1, declares the variable and triggers and asynchronous call on line 2, (i.e., the post request) and it continues its execution from line 3, without waiting for the post request to complete its execution.
Lets say that the post request takes 10 seconds to complete, the value of outerScopeVar will only be set after those 10 seconds.
To try out,
var outerScopeVar; //line 1
$.post('loldog', function(response) { //line 2, takes 10 seconds to complete
outerScopeVar = response;
});
alert("Lets wait for some time here! Waiting is fun"); //line 3
alert(outerScopeVar); //line 4
Now when you execute this, you would get an alert on line 3. Now wait for some time until you are sure the post request has returned some value. Then when you click OK, on the alert box, next alert would print the expected value, because you waited for it.
In real life scenario, the code becomes,
var outerScopeVar;
$.post('loldog', function(response) {
outerScopeVar = response;
alert(outerScopeVar);
});
All the code that depends on the asynchronous calls, is moved inside the asynchronous block, or by waiting on the asynchronous calls.
In all these scenarios outerScopeVar is modified or assigned a value asynchronously or happening in a later time(waiting or listening for some event to occur),for which the current execution will not wait.So all these cases current execution flow results in outerScopeVar = undefined
Let's discuss each examples(I marked the portion which is called asynchronously or delayed for some events to occur):
1.
Here we register an eventlistner which will be executed upon that particular event.Here loading of image.Then the current execution continuous with next lines img.src = 'lolcat.png'; and alert(outerScopeVar); meanwhile the event may not occur. i.e, funtion img.onload wait for the referred image to load, asynchrously. This will happen all the folowing example- the event may differ.
2.
Here the timeout event plays the role, which will invoke the handler after the specified time. Here it is 0, but still it registers an asynchronous event it will be added to the last position of the Event Queue for execution, which makes the guaranteed delay.
3.
This time ajax callback.
4.
Node can be consider as a king of asynchronous coding.Here the marked function is registered as a callback handler which will be executed after reading the specified file.
5.
Obvious promise (something will be done in future) is asynchronous. see What are the differences between Deferred, Promise and Future in JavaScript?
https://www.quora.com/Whats-the-difference-between-a-promise-and-a-callback-in-Javascript
The short answer is : asynchronicity.
Why asynchronous is needed?
JavaScript is single-threaded, meaning that two bits of the script cannot run at the same time; they have to run one after another. In browsers, JavaScript shares a thread with a load of other stuff that differs from browser to browser. But typically JavaScript is in the same queue as painting, updating styles, and handling user actions (such as highlighting text and interacting with form controls). Activity in one of these things delays the others.
You've probably used events and callbacks to get around this. Here are events:
var img1 = document.querySelector('.img-1');
img1.addEventListener('load', function() {
// image loaded
console.log("Loaded");
});
img1.addEventListener('error', function() {
// error caught
console.log("Error printed");
});
<img class="img-1" src="#" alt="img">
This isn't sneezy at all. We get the image, add a couple of listeners, then JavaScript can stop executing until one of those listeners is called.
Unfortunately, in the example above, it's possible that the events happened before we started listening for them, so we need to work around that using the "complete" property of images:
var img1 = document.querySelector('.img-1');
function loaded() {
// image loaded
console.log("Loaded");
}
if (img1.complete) {
loaded();
} else {
img1.addEventListener('load', loaded);
}
img1.addEventListener('error', function() {
// error caught
console.log("Error printed");
});
<img class="img-1" src="#" alt="img">
This doesn't catch images that errored before we got a chance to listen for them; unfortunately, the DOM doesn't give us a way to do that. Also, this is loading one image. Things get even more complex if we want to know when a set of images have loaded.
Events aren't always the best way
Events are great for things that can happen multiple times on the same object— keyup, touchstart etc. With those events, you don't really care about what happened before you attached the listener.
The two main ways to do it correctly: are callbacks and promises.
Callbacks
Callbacks are functions that are passed inside the arguments of other functions, this procedure is valid in JavaScript because functions are objects and objects can be passed as arguments to functions. The basic structure of the callback function looks something like this:
function getMessage(callback) {
callback();
}
function showMessage() {
console.log("Hello world! I am a callback");
}
getMessage(showMessage);
Promise
Although there are ways to keep the callback hell at bay with vanilla JS, promises are growing in popularity and are currently being standardized in ES6 (see Promise).
A promise is a placeholder representing the eventual result (value) of an asynchronous operation
the promise placeholder will be replaced by the result value (if successful) or reason for failure (if unsuccessful)
If you don't need to know when something happened, but just whether it happened or not, then a promise is what you are looking for.
A promise is a bit like an event listener, except that:
a promise can only succeed or fail once
a promise can't switch from fail to success, or vice versa
once you have a result, the promise is immutable
if a promise has succeeded or failed, and you later add a success/failure callback, the correct callback will be called
it doesn't matter that the event occurred before you added the callback
Note: Always return a result from a function inside a Promise, otherwise there's nothing for the subsequent function to act on.
Promise Terminology
A promise can be:
fulfilled: The action relating to the promise succeeded
the asynchronous operation has completed
the promise has a value
the promise will not change again
rejected: The action relating to the promise failed
the asynchronous operation failed
the promise will never be fulfilled
the promise has a reason indicating why the operation failed
the promise will not change again
pending: Hasn't fulfilled or rejected yet
the asynchronous operation hasn't been completed yet
can transition to fulfilled or rejected
settled: Has been fulfilled or rejected and is thus immutable
How to Create a Promise
function getMessage() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('Hello world! I am a promise');
}, 0);
});
}
getMessage().then(function(message) {
console.log(message);
});

Which is more preferable? Dispatch the response of a promise or dispatch an action stating a promise needs to be triggered?

Here are two code samples:
onClick() { // click-handler of a button
axios.get(someUrl)
.then(response => {
// setData is a fn dispatching an action-creator passed through react-redux's connect()
setData(response.data);
});
}
or
// buttonClicked is also a fn dispatching an action-creator
// Difference being the middle-ware handles the entire async process
<button onClick={this.buttonClicked}>Click me</button>
The latter method will use Axios in some middleware, and then dispatch another action which will set the response data in the store.
So this means that the first approach will only dispatch one action, while the second approach will dispatch two actions.
Both ways obviously seem to work, but I would like to know what the best way would be. Is there a downside to either approach?
Disclaimer: This is an opinionated answer, and somewhat rambly.
The thing about promises is that they work the way a human being would think of a promise. So use them like that in your program. Typically IMO you should only use Promises when you know that an event would occur in the normal course of your program workflow, or when you are promising a result.
So for example if you ask for a socket connection, I promise to give one to you whenever I am able to, you don't have to wait for me, just go on and do your thing, as soon as I have done everything needed to get that back to you I will hand it to you; and you can move on in your workflow from the point that needs it. For example, (pseudo code):
var Socket = new Promise(function(resolve, reject) {
resolve(do_something_to_get_a_socket());
});
Socket.then(authenticate()).then(sendData());
etc.
Sticking a promise to an event handler like onClick should be a promise to do something for the user — use it in your code to create threads that will do the heavy lifting of complex processing, while the user is still able to interact with the interface.
For example, in a game a click could fire a dart and you promise that it will animate on the screen (and even if that glitches) you still promise that it will hit the target etc, but the user doesn't have to wait for the promise to be fulfilled to fire another dart.
So use Promises to make your program more readable by you and other coders, and use it to make workflow of your program more realistic to your usecase.
I heavily recommend something like: https://www.npmjs.com/package/redux-api-middleware
This middleware (or others like it) contain quite a few features you would most likely have to write yourself if you were to implement this with just axios in a callback. For example, it will automatically dispatch request, success, and failure actions based on the AJAX call's result.
When dispatching this action using the middleware, many things are taken care of for you.
{
[CALL_API]: {
endpoint: "http://example-api.com/endpoint",
method: "GET",
headers: { ... },
types: [
"GET_X_REQUEST", "GET_X_SUCCESS", "GET_X_FAILURE"
]
}
}
Something like this will automatically fire a "GET_X_REQUEST" action when it begins to load. Then a success or failure action (with appropriate data or error objects attached as a payload) when the AJAX call completes or fails.
Or any similar middleware where Redux ends up handling the entire async process.

Callback is to promise as watch is to ... habit?

I assume everyone knows that a Promise is a data-structure that largely replaces callback as the way to handle asynchrony in Javascript. A Promise can chained, cached, and otherwise manipulated in useful ways.
The Angular $watch function is vital to the functioning of Angular but it takes a callback and has the same shortfalls as callbacks generally. Using a Promise instead would not appropriate because intrinsic to a Promise is the fact it is fulfilled or canceled exactly once.
So I built an analogous structure I have provisionally named a Habit. A Habit is much like a Promise. You construct it with a scope and a watch-expression. Instead of then() it has an on(), which is called with a function. That function will be called whenever the watch-expression changes in the scope.
The return value of the on() is a new Habit, which will be fired with the return value of the function. If that return value is a Promise, it will fire when the Promise is fulfilled.
For example,
util.habit(scope, "user_id")
.on(function(user_id) {
return $.ajax('/users/' + user_id)
.then(function(user) {
return user.name;
});
});
would create a Habit that fires whenever the user_id changes in the scope and invokes its on-functions with the new user's name.
My question are
Is this brilliant, obvious, old-hat, or stupid?
Why?

Resources