【问题标题】:Using async In Node Module - How to Return Results? [duplicate]在节点模块中使用异步 - 如何返回结果? [复制]
【发布时间】:2017-01-06 06:28:25
【问题描述】:

我正在为我的公司编写一个内部 NPM 模块,以便应用程序可以与我们拥有的硬件设备进行交互,我们已经编写了一个用于与之通信的库。问题是,我尝试编写的一种方法需要异步执行。我希望函数发送一个从设备读取的命令,等待它返回(设备库处理这个),然后我解析结果。我希望其他开发人员能够调用exports.getResolution() 来获取值。这是我的文件的 sn-p 和相关部分:

var async = require('async');

exports.getResolution = async.series([
    function(callback) {
    board.sendAndReceive(bufferlib.generateBuffer("read", "0x00001220", "0x00000004"), (function(received) {
            var hex = bufferlib.sortReceivedHex(received);
            var status = parseInt('0x' + hex.substring(0, 1), 16);
            var verticalResolution = parseInt('0x' + hex.substring(1, 4), 16);
            var horizontalResolution = parseInt('0x' + hex.substring(5, 9), 16);
            callback(null, {
                'status': status,
                'vertical': verticalResolution,
                'horizontal': horizontalResolution
            });
        }));
    }
],
// optional callback
function(err, results) {
    status = results[0];
    return results[0];
});

console.log(exports.getResolution);

我尝试过回调地狱、Promises、bluebird、ES6 异步函数和一堆其他解决方案,但我就是想不通这个。我最近的尝试使用 async 节点模块来尝试异步执行代码,这很有效,但现在我只需要获取 exports.getResolution 来返回最终回调接收的实际值。我究竟做错了什么?我能做些什么来完成这项工作?谢谢。

【问题讨论】:

    标签: javascript node.js asynchronous npm async.js


    【解决方案1】:

    尝试使异步调用同步不是一个好主意。您需要做的是注册一个在结果存在时执行的方法。通常这些方法称为回调,但 Promises 是完成等待异步结果的更好方法。

    exports.getResolution = function() {
        return new Promise(function(resolve, reject) {
            function receiveHandler(received) {
                var hex = bufferlib.sortReceivedHex(received);
                var status = parseInt('0x' + hex.substring(0, 1), 16);
                var verticalResolution = parseInt('0x' + hex.substring(1, 4), 16);
                var horizontalResolution = parseInt('0x' + hex.substring(5, 9), 16);
    
                // If status would say something about it's success you could also
                // use reject instead of resolve to indicate failure
                resolve({
                    'status': status,
                    'vertical': verticalResolution,
                    'horizontal': horizontalResolution
                });
            }
    
            board.sendAndReceive(bufferlib.generateBuffer("read", "0x00001220", "0x00000004"), receiveHandler);
        }
    }
    
    // Usage
    exports.getResolution().then(function(response) {
      console.log('succesfully received response:', response);
    }, function(response) {
      console.log('something went wrong:', response)
    });
    

    【讨论】:

      【解决方案2】:

      正确的做法是给你的getResolution 函数一个回调参数。这才是真正应该做到的。

      exports.getResolution = function(callback) {
          board.sendAndReceive(bufferlib.generateBuffer("read", "0x00001220", "0x00000004"), function(received) {
              var hex = bufferlib.sortReceivedHex(received);
              var status = parseInt('0x' + hex.substring(0, 1), 16);
              var verticalResolution = parseInt('0x' + hex.substring(1, 4), 16);
              var horizontalResolution = parseInt('0x' + hex.substring(5, 9), 16);
              callback(null, {
                  'status': status,
                  'vertical': verticalResolution,
                  'horizontal': horizontalResolution
              });
          });
      }
      
      
      console.log(exports.getResolution(function (err, results) {
          console.log(results);
      }));
      

      以上方式是JS中正确的做事方式。但是,如果您绝对需要让 getResolution 看起来是同步的,那么您可能需要查看this answer。但您似乎需要修改一些 board 函数以允许轮询...

      【讨论】:

      • 感谢您的回复。如果可能的话,我真的很想避免潜在的回调地狱,但我很感激你在回复中投入的时间和想法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 1970-01-01
      • 2021-07-31
      • 2023-04-01
      相关资源
      最近更新 更多