node 7.6 async await issues with returning data

匿名 (未验证) 提交于 2019-12-03 02:43:01

问题:

I am working on a simple TCP client for a server and am using the latest node 7.6 because of the async/await functions. I'm new to node and asynchronous coding, so I apologize if this is stupidly easy.

I want to run a function that calls the callServer() function with specific parameters, wait until it finishes getting the data, and return the data as a variable.

Here is my code:

'use strict' const net = require('net')  var formattedJson = funcRequestToJson("Server.GetStatus", false)  doThings()  async function doThings() {     var info = await callServer() }  async function callServer() {     var client = new net.Socket()      client.connect(1705, '192.168.28.16', () => {         console.log('connected to server')         client.write(formattedJson)     })      client.on('data', (data) => {         client.destroy()         //return await data         console.log(data.toString())     })      client.on('close', () => {     }) }  // method and paramBool are always required // macAddress, paramKey, paramValue are required for if paramBool is true function funcRequestToJson(method, paramBool, macAddress, paramKey, paramValue) {     var objectRequest = {}      objectRequest[ "jsonrpc" ] = "2.0"     objectRequest[ "method" ] = method     objectRequest[ "id" ] = 0     if (paramBool == true) {         objectRequest[ "params" ] = {             "client": macAddress,             [paramKey]: paramValue         }     }      var json = (JSON.stringify(objectRequest) + '\r\n')      return json } 

So I didn't declare objectRequest() as async because it's not waiting on the server, but I think callServer() should be async, right? I know this can be done with promises, but I wanted to use async/await and this seems to be right.

Now, I want to return the data that comes from inside callServer() and client.on('data', (data) but I can't seem to figure out how to do it asynchronously. I would think there'd be a way to make an async function and call it with await like I tried (await return data) but it never works right.

I'm sorry if this is terribly convoluted, but I've been poring over async node tutorials for the past week and am still stuck.

Thanks!

回答1:

Async/Await relies on code that uses promises for async operations. So you need to return a promise from any async operation in order to use it with async/await.

So, callServer() needs to return a promise that is resolved when the async operation inside it is done. In fact, you can only await an async operation in a function if that function returns a promise. await saves you from having to write .then() handlers on promises, but async/await does not magically know when async operations are done. You still have to wrap them in promises.

Here's an example of how you could make callServer() return a promise:

async function callServer(formattedJson) {     return new Promise((resolve, reject) => {         let client = new net.Socket()          client.connect(1705, '192.168.28.16', () => {             console.log('connected to server')             client.write(formattedJson)         })          client.on('data', (data) => {             resolve(data);             client.destroy()         })          client.on('close', () => {         })          client.on('error', reject);      }); } 

Sample Usage:

try {     var info = await callServer(funcRequestToJson("Server.GetStatus", false)); } catch(e) {     // error here } 

Just to show you what await is doing, in ES5 (without async/await), the sample usage would be this:

callServer(funcRequestToJson("Server.GetStatus", false)).then(info => {     // info is available here }).catch(err => {     // error here }); 

So, await is just letting you avoid writing the .then() handler. Internally in the execution of the code, there's just a promise that the interpreter sets up a .then() handler for so it will know when that promise is resolved. This is syntactical sugar, not really any magic with async operations. You still have to use promises for all your async operations. You can use await instead of .then() and your code will appear more sequential even though it's really the same under the covers.

People think that await allows one to write asynchronous code as if it was synchronous, but that isn't really the case, especially if you handle errors and understand concurrency issues. It will look more synchronous, but isn't actually any more synchronous than it was with .then() in ES5.

And, watch out for error handling. In people's quest to write synchronous looking code, people seem to completely forget to handle rejected promises in their async operations (which are handled with try/catch when using await). I'm personally not yet convinced that ES6 is a step forward when it comes to error handling as the early indications are that ES6 seems to encourage people to just forget about error handling or get lazy and not do it, whereas it's easier when using .then() to just know that there should be a .catch() somewhere for it to be solid code. Maybe that's just a learning process, but it seems to be an early issue when people use await.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!