2017-02-24 58 views
-1

我正在为服务器开发一个简单的TCP客户端,并且因为异步/等待功能而使用最新的节点7.6。我是新来的节点和异步编码,所以我很抱歉,如果这是非常容易的。节点7.6 async等待返回数据的问题

我想运行一个函数,该函数使用特定参数调用callServer()函数,等到它完成获取数据并将数据作为变量返回。

这里是我的代码:

'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 
} 

所以我没有申报objectRequest()的异步因为它没有等待服务器,但我认为callServer()应该是异步,对不对?我知道这可以通过承诺来完成,但我想使用异步/等待,这似乎是正确的。我想要返回来自callServer()和client.on('data',(data)内部的数据,但我似乎无法弄清楚如何异步执行它。我想在那里'd是一种创建异步函数的方法,并像我试着一样等待(等待返回数据),但它永远不能正常工作。

对不起,如果这是非常复杂的,但我一直在俯视在过去的一周异步节点教程和我仍然坚持。

谢谢!

+0

异步/等待依赖于使用承诺进行异步操作的代码。因此,您需要从任何异步操作中返回一个承诺,以便与async/await一起使用它。因此,'callServer()'需要返回一个promise,在它内部的异步操作完成时解析。事实上,如果函数返回一个promise,你只能等待函数中的异步操作。 'await'使你不必在promises上编写'.then()'处理程序,但async/await不会奇迹般地知道异步操作何时完成。你仍然必须包装他们的承诺。 – jfriend00

+0

啊,我不知道!正如我所说的,我是新来的异步编程方法。我不希望你必须写我的代码或任何东西,但是你能否指引我参考一些涉及承诺的参考资料/指南/教程?我找到了一些,但他们都很老。 –

+0

您可以从MDN开始(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。有很多很好的在线资源。 Javascript中的承诺自第一个标准以来一直保持一致,并且全部都编码在ES6中,因此您不应该在网上找到任何主要的不一致之处。只要避免与jQuery的Deferred或Promises有任何关系,因为它们已经相当不规范(他们试图在jQuery 3.x中修复它)。 – jfriend00

回答

1

异步/等待依赖于使用承诺为异步操作的代码。因此,你需要ŧ o从任何异步操作中返回一个承诺,以便与异步/等待一起使用它。

因此,callServer()需要返回一个承诺,在其内部的异步操作完成时解决。事实上,如果函数返回一个promise,你只能等待函数中的异步操作。 await使您不必编写.then()处理程序的承诺,但async/await不会奇迹般地知道异步操作何时完成。你仍然必须包装他们的承诺。

这里是你能怎么做callServer()返回一个承诺的例子:

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); 

    }); 
} 

用法示例:

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

只是为了告诉你什么是伺机在做什么,在ES5(不async/await),示例的用法如下:

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

因此,await只是让你避免编写.then()处理程序。在执行代码的内部,只是承诺解释器会设置一个.then()处理程序,以便知道何时解决了该承诺。这是语法糖,对于异步操作来说并不是什么神奇的东西。您仍然必须对所有异步操作使用promise。您可以使用await而不是.then(),并且您的代码将显示更多顺序,即使它们在封面下实际上是相同的。

人们认为await允许编写异步代码,就好像它是同步代码一样,但事实并非如此,尤其是在处理错误和理解并发问题时。它看起来更同步,但实际上并没有比ES5中的.then()更同步。

并且,注意错误处理。在人们寻求编写同步代码的过程中,人们似乎完全忘记了在他们的异步操作中处理被拒绝的承诺(在使用await时使用try/catch处理)。我个人还不相信ES6在错误处理方面向前迈进了一步,因为早期的迹象表明,ES6似乎鼓励人们忘记错误处理或懒惰而不这样做,而使用只是知道应该有一个.catch()的地方,因为它是可靠的代码。也许这只是一个学习过程,但当人们使用await时似乎是一个早期问题。

+0

我什至不能告诉你所有的帮助!有趣的是,当ES5承诺发挥作用时,您给我的等待例子不起作用。虽然我并不担心;我要研究承诺。太感谢了! –