Promise is a way for asynchronous code to implement control flow. This way you can make your code clean, readable, and robust.
For example, the callback code that you use to asynchronously process a file event:
Fs.readfile ('directory/file-to-read', function (err, file) { if (Error) { //handle error else { // Do something with the file }});
You may have heard that node will soon get into a callback hell, that's why. As a node developer you will encounter a lot of asynchronous code, and you will encounter a lot of callbacks (callback).
These callbacks are still relatively simple. However, you will need to continue to do other actions after an action is completed, so the callback will be nested continuously. You'll find that soon the code is hard to read, not to mention maintenance. Like what:
Fs.readfile ('Directory/file-to-read', function (err, file) {if(Error) {//Handle Error}Else { //Do something with the fileFs.mkdir ('directory/new-directory', function (err, file) {if(Error) {//Handle Error}Else { //New directory has been madeFs.writefile ('Directory/new-directory/message.txt', function (err, file) {if(Error) {//Handle Error}Else { //File successfully created } }); } }); }});
In the example above, I want to read a file asynchronously, then create a directory and create a file. You can see how ugly nested code this simple three-step task becomes, especially if you add logic controls to the code again, and the code is unthinkable and ugly.
Why do we use promise in node
As an example of the above-mentioned code, we will explore how to use promise to solve the problems mentioned above:
Fs.readfileasync (' Directory/file-to-read ') . Then (function(fileData) { return fs.mkdirasync (' directory/new-directory '); }) . Then (function() { return fs.writefileasync (' directory/new-directory/ Message.txt '); })
Promise provides us with a clearer and more robust way to write asynchronous code. The first method returns a promise, which can call the ' then ' method on the promise. You can also call more ' then ' after ' then '. Each ' then ' can access the information returned by the previous ' then '. The example returned by every ' then ' method can call a ' then ' again. This is often another asynchronous invocation.
Promise also makes it easier for you to break down your code into multiple files. Like what:
function readfileandmakedirectory () { return Fs.readfileasync (' Directory/file-to-read ' ). Then ( function (fileData) { return fs.mkdirasync (' directory/new-directory ' ); });} // the following would execute once the file has been read and a new directory have been made< /span> readfileandmakedirectory (). Then ( function () {
return fs.writefileasync (' Directory/new-directory/message.txt ') ); })
It is easy to create a method that returns promise. This is useful when you need to break down the code into different files. For example, you might have a route that reads a file, reads its contents, and returns the contents of the article in JSON form. You can break down the code into multiple components that return promise.
//Routes/index.jsvarRouter = require (' Express '). Router ();varGetfileexcerpt = require ('.. /utils/getfileexcerpt ') Router.get (‘/‘,function() {Getfileexcerpt.then (function(fileexcerpt) {Res.json ({message:fileexcerpt}); });}); Module.exports=router;//Utils/getfileexcerpt.jsvarPromise = require (' Bluebird '));varFS = Promise.promisifyall (Require (' FS '))); Module.exports=functionGetpost () {returnFs.readfileasync (file, ' UTF8 '). Then (function(content) {return{excerpt:content.substr (0, 100) } });}
The above code also makes it clear that any of the returned ' then ' can be called ' then ' later.
Handling Errors
Using promise to handle errors is straightforward. When an error occurs during the execution of a heap of ' then ' methods, Bluebird will find the nearest . Catch method to execute. You can embed catch methods in the ' Then ' chain. The above example can be rewritten as:
Fs.readfileasync (' Directory/file-to-read ') . Then (function(fileData) { return fs.mkdirasync (' directory/new-directory '); }) . Then (function() { return fs.writefileasync (' directory/new-directory/ Message.txt '); }) . Catch (function(error) { //do something with theerror and handle it } );
You can use catch to handle errors.
But the module I want to use does not return promise
You will notice that the above example uses ' Fs.writefileasync ' and ' Fs.mkdirasync '. If you check node's documentation you will see that these methods do not exist. FS does not return promise.
Nonetheless, Bluebird provides a very useful feature to promise modules that do not return promise. For example, to promise the FS module, simply require the Bluebird module and a Promise FS module.
var Promise = require (' bluebird '); var fs = Promise.promisifyall (Require (' FS '));
Create your own Promise
Because you can promise the module, you don't need to write a lot of code to create promise. Then, even knowing how to create it is necessary. Creating promise requires a callback method that provides resolve and reject. Each one needs to be passed:
// Span style= "Color:rgb (0,128,0)" >mypromise.js var Promise = require (' Bluebird ' ); module.exports = function () { return new Promise (function (Resolve, Reject) {tradiationcallbackbasedthing ( function (Error, data) { if (err) { Reject (ERR); } else {Resolve (data)}}); });}
This completes the promise. Next, you can use this technique to write the promise form that you want to promise.
Test Promise
When I tested the server code, my favorite frame was mocha and chai. Be aware that when testing asynchronous code you need to tell Mocha when the asynchronous code is done. Otherwise, he will only continue to perform the following tests, which will cause an error.
At this point, simply call the callback method provided by Mocha in the IT section:
function (done) { + '/... /fixtures/test-post.txt ') . Then (function(data) { data.should.equal (' some Content inside the post '); Done (); }) . Catch (done);});
Promise is very useful, and it is strongly recommended that you use promise when writing asynchronous code using node.
You can learn more by reading the Bluebird API documentation.
Bluebird-nodejs of Promise