One of the things that you have to get used to when switching to Javascript is that asynchronous (Asynchronous) is different from the concept of synchronous (Synchronous) that we are familiar with in languages like C # .NET or PHP.
1. Callback and Callback hell
Asynchronous programming, we still use a mechanism called callback:
1 2 3 4 5 6 7 8 | <span class="token keyword">function</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'a'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">setTimeout</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'hello world!'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token number">2000</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'b'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
The setTimeout
function aims to simulate the environment like you get data from a certain url. What will be printed out in the browser console will be:
1 2 3 4 | a b hello world! |
Asynchronous here means that the browser will not wait until it gets data to run the next command ( console.log('b')
) but will keep running and the data will print at any time. there. Print out hello wolrd! can be a few minutes from the printout b, depending on the parameters we enter. The question is that the callback has already solved the asynchronous problem, why it is necessary to generate Promise. Promise is basically an asynchronous programming technique but has advantages over callback, typically as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">function</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> <span class="token function">setTimeout</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> a <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> a <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">setTimeout</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> a <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token number">2</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> a <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">setTimeout</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> a <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token number">3</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> a <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
This is called callback hell, when the http requests depend on each other, the sense of the endless repeated function is difficult to follow. Luckily, Promise helps us to solve this problem.
2. Promise and Promise chaining
Basically Promise carries its literal meaning – a promise. It’s like the kind your mother promised when she was a child: if your kids are good, they will go to the park. A promise, as you know, can or may not be fulfilled depending on the person making the promise and other external conditions. It only describes what you will get if all conditions are fulfilled. Obedient for example, obedient, everything also has. Rewrite the above example with Promise as follows:
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">function</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">resolve <span class="token punctuation">,</span> reject</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> $ <span class="token punctuation">.</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token string">"http://google.com"</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> paramOne <span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> paramX <span class="token operator">:</span> <span class="token string">'abc'</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error <span class="token punctuation">,</span> data</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu không ngoan hoặc nếu tự dưng mẹ đang bực</span> <span class="token function">reject</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// nếu ngoan và mẹ thì đang vui</span> <span class="token function">resolve</span> <span class="token punctuation">(</span> data <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
This time we take the example get content of a url to simulate more accurately because it has an error case, if it is setTimeout
there will never be an error. In the above function, resolve is like her mother giving you a reward. If you forget to resolve, you won’t get anything like when she forgot, and you have to say so. Similar to reject, the thing passed to the reject
function must be an instance of the error, otherwise you won’t be able to catch it later. Of course if you don’t call reject, you will never know if you have a reward. At this point, you may think “Nothing special”, but Promise has two convenient then
and catch
methods.
1 2 3 4 5 6 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">data</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'page content: '</span> <span class="token operator">+</span> data <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">catch</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The then function has 2 parameters in the order of success handler
and failure handler
but usually people will not pass in the second parameter. Then the result is a Promise, so we can continue calling then from the object. returns – also known as Promise chaining as shown below. If for some reason you do not pass both parameters or 2 parameters that are not a function then a new Promise will be returned with the value of the previously called Promise.
1 2 3 4 5 6 7 8 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">result</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">catch</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The first then function has two non-function parameters so the Promise returned by the test () function will go through the first then function and to the second then without any changes. If the handlers (either success handler
or failure handler
) return a value then the function will return a Promise with that value and the state is successful, if return or throw an error then the function will return a Promise with the value of error. and state is failure.
1 2 3 4 5 6 7 8 9 10 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">'hello'</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">result</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'successful with result '</span> <span class="token operator">+</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'failed with error '</span> <span class="token operator">+</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Results received will be successful with result hello.
1 2 3 4 5 6 7 8 9 10 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token string">'oops!'</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">result</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'successful with result '</span> <span class="token operator">+</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">'failed with error '</span> <span class="token operator">+</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
then the received result is failed with error oops!
.
The catch function takes an input parameter which is a failure handler so it only applies to errors. Calling catch
is exactly the same as calling then
with the first parameter undefined. The following two callings are completely equivalent:
1 2 3 4 5 6 7 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">catch</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">undefined</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
If test()
returns a Promise with a successful state then console.log(error)
will never be called and the Promise return from test()
will be returned for the next then
or catch
(if applicable).
Rewrite example 2 using Promise as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <span class="token keyword">function</span> <span class="token function">getUrl</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">resolve <span class="token punctuation">,</span> reject</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> $ <span class="token punctuation">.</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token string">"http://example.com/url1"</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> paramOne <span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> paramX <span class="token operator">:</span> <span class="token string">'abc'</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error <span class="token punctuation">,</span> data</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> id <span class="token operator">=</span> data <span class="token punctuation">.</span> id <span class="token punctuation">;</span> <span class="token function">resolve</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">getUrl1</span> <span class="token punctuation">(</span> <span class="token parameter">id</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">resolve <span class="token punctuation">,</span> reject</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> $ <span class="token punctuation">.</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token string">"http://example.com/url1"</span> <span class="token operator">+</span> id <span class="token punctuation">,</span> <span class="token punctuation">{</span> paramOne <span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> paramX <span class="token operator">:</span> <span class="token string">'abc'</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error <span class="token punctuation">,</span> data</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> id <span class="token operator">=</span> data <span class="token punctuation">.</span> id <span class="token punctuation">;</span> <span class="token function">resolve</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">getUrl</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">id</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">getUrl1</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">id1</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> id1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">catch</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
It’s easier to see callback hell above, right? We can call then and catch interwoven to make it easy to see as follows:
1 2 3 4 5 6 7 8 9 10 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">result</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">catch</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">result</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">catch</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
It is also possible to not use catch at all, but it will seem incomprehensible with the above interlaced approach:
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token function">test</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">result</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">then</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">result</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
3. Switch from callback to Promise
With the old Browser, Promise does not support native, so we often have to use external libraries like async or q. I will show you how to switch from callback to Promise using Mongoose library. For simplicity I take the classic example of todo and assume you already have the todo schema
:
models / todo.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token string">"use strict"</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> mongoose <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'mongoose'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> timestamps <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'mongoose-timestamp'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> TodoSchema <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">mongoose <span class="token punctuation">.</span> Schema</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> name <span class="token operator">:</span> <span class="token punctuation">{</span> type <span class="token operator">:</span> String <span class="token punctuation">,</span> require <span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> <span class="token string">'name can not be blank'</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> description <span class="token operator">:</span> <span class="token punctuation">{</span> type <span class="token operator">:</span> String <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> minimize <span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> TodoSchema <span class="token punctuation">.</span> <span class="token function">plugin</span> <span class="token punctuation">(</span> timestamps <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> Todo <span class="token operator">=</span> mongoose <span class="token punctuation">.</span> <span class="token function">model</span> <span class="token punctuation">(</span> <span class="token string">'Todo'</span> <span class="token punctuation">,</span> TodoSchema <span class="token punctuation">)</span> <span class="token punctuation">;</span> module <span class="token punctuation">.</span> exports <span class="token operator">=</span> Todo <span class="token punctuation">;</span> |
repository / todoRepository.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token string">"use strict"</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> Todo <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'models/todo'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">Q</span> <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">"q"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">getList</span> <span class="token punctuation">(</span> <span class="token parameter">params</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> deferred <span class="token operator">=</span> <span class="token constant">Q</span> <span class="token punctuation">.</span> <span class="token function">defer</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Todo <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error <span class="token punctuation">,</span> todos</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">{</span> deferred <span class="token punctuation">.</span> <span class="token function">reject</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> deferred <span class="token punctuation">.</span> <span class="token function">resolve</span> <span class="token punctuation">(</span> blogs <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> deferred <span class="token punctuation">.</span> promise <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
With Browser support Promise we don’t need to use external libraries anymore. todoRepository.js
will revise a bit as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token string">"use strict"</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> Todo <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'models/todo'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">getList</span> <span class="token punctuation">(</span> <span class="token parameter">params</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">resolve <span class="token punctuation">,</span> reject</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Todo <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">error <span class="token punctuation">,</span> todos</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span> <span class="token punctuation">(</span> error <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">resolve</span> <span class="token punctuation">(</span> todos <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
In a nutshell Promise is so, very simple to understand, about other async libs will probably find the opportunity to share with everyone in another post.