async and await and promise (asynchronous operation problems in nodejs)

  • 2021-07-26 06:26:41
  • OfStack

Example a scenario when writing an article details page: first change PV in article details, then read article details, and then look up the article comments and author information according to article Id in article details. Render the article details page after obtaining all the data. Database operations are asynchronous, and the most direct way to think of is the callback function of 1 layer and 1 layer. The problem comes out: 10 points are unsightly, and if the layer is 1 point more, there will be more trouble. How to solve it? In order to deal with asynchronous operation, the industry has also spelled out what async, q, bluebird and co are handled in different ways, and each has its own merits. If you are interested, you can learn about it. However, you are pleasantly surprised to find that nodejs 7.6 already supports async/await in ES7 by default, and it is a pleasure to use it in combination with promise objects in ES6.

The main benefit of Async/await is that it avoids the callback hell (callback hell) problem.

Basic concepts:

async means that this is an async function, and await can only be used in this function.

await means waiting for promise to return the result before continuing.

await should be followed by an promise object (of course, other return values don't matter, but that doesn't make sense …)

Examples:

Gets the return value:


var sleep = function (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      //  Return   ' ok'
      resolve('ok');
    }, time);
  })
};
var start = async function () {
  let result = await sleep(3000);
  console.log(result); //  Received   ' ok'
};

Capture errors:


var sleep = function (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      //  Error in simulation, return   ' error'
      reject('error');
    }, time);
  })
};
var start = async function () {
  try {
    console.log('start');
    await sleep(3000); //  Got it here 1 Errors returned 
    
    //  So the following code will not be executed 
    console.log('end');
  } catch (err) {
    console.log(err); //  Errors caught here  `error`
  }
};

In a loop:


var start = async function () {
  for (var i = 1; i <= 10; i++) {
    console.log(` At present, it is the first ${i} Secondary wait ..`);
    await sleep(1000);
  }
};

Closures are not required in recycling, and each loop will be blocked.

The scenario mentioned above: (comprehensive use)


var showArticle = async function () {
    await new Promise(function (resolve, reject) {
      PostModel.incPv(postId, function (result) {
        resolve(result);
      });
    });// pv  Plus  1
    var post = await new Promise(function (resolve, reject) {
      PostModel.getPostById(postId, function (article) {
        resolve(article);
      });
    });//  Get article information 
    await new Promise(function (resolve, reject) {
      userModel.getUserById(post.author,function (author) {
        post.author=author;
        resolve();
      })
    });// Get the author of the article 
    var comments = await new Promise(function (resolve, reject) {
      CommentModel.getComments(post._id, function (comment) {
        resolve(comment);
      });
    });//  Get all messages for this article 
    for(var i=0;i<comments.length;i++){
      await new Promise(function (resolve, reject) {
        userModel.getUserById(comments[i].author,function (author) {
          comments[i].author=author;
          resolve();
        })
      });// Get the author of the article message 
    }
    if (!post) {
      req.session.error = ' This article does not exist ';
      return res.redirect('/post');
    }
    res.render('post',{post: post, comments: comments});
  };
  showArticle();

Related articles: