async, await, promise learning summary


Because I am getting a nodejs server recently, the result is the rpc implemented by zeromq. It was found that the rpc would get stuck. After printing the message, the zeromq message was mainly lost. After sending it, the receiving end did not receive it. Then I found out that the asynchronous code called async / await is used in the sample code. I don't understand it, so I found some materials to learn and take notes.

problem

  1. Why use asynchronous mode in zeromq?
  2. How to get the return value of async function?
    This is the code from the beginning:
function sendMsg(server, msg, uniqueId) {
 if (!this.socket) {
  return null;
 }

 var rid;
 if (uniqueId === undefined) {
  rid = uuid.v4() + '_' + this.id;
 } else {
  rid = uniqueId;
 }

 this.socket.send([MDP.REQUEST, server, rid, JSON.stringify(msg)])
 return rid;
}

understanding

In general, Promise and async / await are both asynchronous calls, and can solve the problem of 'regional callback'. And async / await is written more in line with the way of synchronous code, read it better to understand, refer to [1]

Promise

Promise was originally designed to solve the callback problem, refer to [2] [3]

Promise is an object, which represents the final completion or failure of an asynchronous operation

Simply put, there will be success and failure after an asynchronous call. You can handle them uniformly after the asynchronous call is completed, and there is no need to process callbacks in each branch. That is, there is no need to pass the callback in, but the final processing of a Promise object. How to deal with it? The point in time is the Promise.then function.

const promise1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo');
  }, 300);
});

promise1.then(function(value) {
  console.log(value);
  // expected output: "foo"
});

console.log(promise1);
// expected output: [object Promise]

In addition, note that the then parameter is a function, and many times you see the arrow function [4], so it will feel a bit strange at the beginning.

async

Async is easy to understand, it is asynchronous function. Reference [5] It
should be noted that its return value is a Pomise object, so my initial sendMsg function is written in the following form, and the return value rid obtained by synchronously calling sendMsg is wrong. I also encountered problems at the beginning

async function sendMsg(server, msg, uniqueId) {
 // 省略
 await this.socket.send([MDP.REQUEST, server, rid, JSON.stringify(msg)])
 return rid;
}

The other is that you can use await in async to interrupt the async function. I understand that the yield thrown back at this time is a Promise object, even if you await immediately the return value itself is a Promise object

async function test1(){
 var a = await 3;
 return a;
}
console.log(test1())
console.log(test1().then((resolve, reject)=>{
 console.log('resolve:', resolve)
}))
//结果
Promise { <pending> }
Promise { <pending> }
resolve: 3

await

Await probably has the following points, refer to [6]:

  • Can only be used in async function
  • The await expression will suspend the execution of the current async function, waiting for the completion of the Promise processing
  • Because it is an asynchronous call, if async is interrupted by await at this time, it will continue to execute, but it will not block and stop here. The returned Promise object, but this Promise object has not yet been processed, so the returned Promise.then function has not yet begun to execute.
    Take the example in [5]
var resolveAfter2Seconds = function() {
  console.log("starting slow promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve("slow");
      console.log("slow promise is done");
    }, 2000);
  });
};

var resolveAfter1Second = function() {
  console.log("starting fast promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve("fast");
      console.log("fast promise is done");
    }, 1000);
  });
};

var concurrentStart = async function() {
  console.log('==CONCURRENT START with await==');
  const slow = resolveAfter2Seconds(); // starts timer immediately
  const fast = resolveAfter1Second(); // starts timer immediately
  // 1. Execution gets here almost instantly
  console.log(await slow); // 2. this runs 2 seconds after 1. 
  console.log(await fast); // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved
}

result:

==CONCURRENT START with await==
starting slow promise
starting fast promise
fast promise is done
slow promise is done
slow
fast

(1) The two functions resolveAfter2Seconds and resolveAfter1Second are executed in the same frame without await, so the first three prints will come out immediately
(2) The fourth print fast promise is done will be printed at the end of the first second, because The resolveAfter1Second function is executed, and the Promise is processed
(3) The last three prints are printed together, mainly fast to be printed last, because await slow blocks the execution of the last console.log of async. Even if the fast promise has been dealt with

Solution and summary

Pull the asynchronous function out of another function, it will not affect the return value of sendMsg

async function send(msg) {
    if (!this.socket) {
        return;
    }
    try {
        await this.socket.send(msg);
    }catch(err){
        console.error('unable to send')
    }
}

function sendMsg(server, msg, uniqueId) {
 // 省略
 send.call(this, [MDP.REQUEST, server, rid, JSON.stringify(msg)]).then((resolve, reject)=>{
  console.log('send result...........', resolve, reject)
 });
 return rid;
}

reference

[1] Evolution of asynchronous processing in Nodejs
[2] Promise
[3] Promise uses
[4] arrow functions
[5] async
[6] await
[7] Async / Await in Nodejs
[8]
[9] Master async / await in Node.js

Published 41 original articles · praised 7 · 20,000+ views

Guess you like

Origin blog.csdn.net/pkxpp/article/details/104748170