异型等待和非异步功能的麻烦



我正在尝试处理使用异步功能的库,并且有点丢失。我想调用一个返回字符串但被绊倒的函数。这是我到目前为止所拥有的。Zeroex库的功能似乎都在使用异步/等待,因此我的理解是我只能从另一种异步方法中调用它们。但这不仅会导致链反应意味着每种方法都需要异步?还是我错过了什么?

function main() {
    var broker = zmq.socket('router');
    broker.bindSync('tcp://*:5671');

    broker.on('message', function () {
    var args = Array.apply(null, arguments)
        , identity = args[0]
        , message = args[1].toString('utf8');
        if(message === 'TopOfBook') {
            broker.send([identity, '', getTopOfBook()]);
        }
        //broker.send([identity, '', 'TEST']);
        //console.log('test sent');
    })
}
async function getTopOfBook() {
    var result: string = 'test getTopOfBook';
    const EXCHANGE_ADDRESS = await zeroEx.exchange.getContractAddress();
    const wethTokenInfo = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync('WETH');
    const zrxTokenInfo = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync('ZRX');
    if (wethTokenInfo === undefined || zrxTokenInfo === undefined) {
        throw new Error('could not find token info');
    }
    const WETH_ADDRESS = wethTokenInfo.address;
    const ZRX_ADDRESS = zrxTokenInfo.address;

    return result;
}
main();

函数getTopofbook((没有将任何内容返回到主((函数,因此经纪人永远不会发送结果。评论的经纪人send((带有"测试"的运行良好。感谢您的查看。

编辑:我试图制作主要方法异步,以便我可以使用等待,但是这是一个错误,我只能在异步函数中使用等待。Broker.on((呼叫可以引起这一点吗?

  const main = async () => {
      try{
      var broker = zmq.socket('router');
      broker.bindSync('tcp://*:5671');

      broker.on('message', function () {
      var args = Array.apply(null, arguments)
          , identity = args[0]
          , message = args[1].toString('utf8');
          console.log(message);
          if(message === 'TopOfBook') {
>>            var test = await getTopOfBook();
              console.log('in top of book test');
              broker.send([identity, '', test]);
          }
          //broker.send([identity, '', 'TEST']);
          //console.log('test sent');
      })
      } catch (err) {
          console.log(err);
      }
  }

编辑2:我当前的工作代码,感谢所有有建议/解决方案的人!显然,我必须填写getTopofbook((函数才能返回实际结果。如果您有更多建议,请将他们发送给他们。我正在尝试建立一个后端,该后端将从Geth RPC获取数据并将其发送到C#GUI前端。

var main = function() {
    try{
    var broker = zmq.socket('router');
    broker.bindSync('tcp://*:5672');
    broker.on('message', function () {
    var args = Array.apply(null, arguments)
        , identity = args[0]
        , message = args[1].toString('utf8');
        if(message === 'TopOfBook') {
            getTopOfBook().then((result) => {
                broker.send([identity, '', result])
            });
        }
    })
    } catch (err) {
        console.log(err);
    }
}
async function getTopOfBook() {
    var result: string = 'test getTopOfBook';
    const EXCHANGE_ADDRESS = await zeroEx.exchange.getContractAddress();
    const wethTokenInfo = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync('WETH');
    const zrxTokenInfo = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync('ZRX');
    if (wethTokenInfo === undefined || zrxTokenInfo === undefined) {
        throw new Error('could not find token info');
    }
    const WETH_ADDRESS = wethTokenInfo.address;
    const ZRX_ADDRESS = zrxTokenInfo.address;

    return result;
}
main();

回调函数需要为异步

broker.on('message', async function () {
    var args = Array.apply(null, arguments)
        , identity = args[0]
        , message = args[1].toString('utf8');
        if(message === 'TopOfBook') {
            var test = await getTopOfBook();
            broker.send([identity, '', test]);
        }
        //broker.send([identity, '', 'TEST']);
        //console.log('test sent');
    })

您缺少这样的观点,即异步函数只是编写代码的一种方法。每个异步函数实际上所做的就是产生诺言。这就是为什么您可以await任何承诺,并且可以与任何使用异步的库进行交互,而无需自己使用异步功能。

当您调用异步函数时,它应该返回承诺(在异步函数上会自动发生(。承诺不过是带有then方法的对象。这种方法接受回调,您可以在其中处理其余的逻辑。

function main() {
    var broker = zmq.socket('router');
    broker.bindSync('tcp://*:5671');

    broker.on('message', function () {
    var args = Array.apply(null, arguments)
        , identity = args[0]
        , message = args[1].toString('utf8');
        if(message === 'TopOfBook') {
            return getTopOfBook().then( result => 
                broker.send([identity, '', result])
            ) // If the broker also returns a promise, you can continue the flow here
            .then(()=> console.log('test sent'))
        }
    })
}

我个人根本不喜欢异步,因为涉及太多魔术,使人们忘记了承诺和异步代码的实际性质。

同样,在处理诺言时,您应该始终记住返回任何可以致电/生成的承诺,以便外部代码可以继续链条并处理错误消息。

您的功能getTopOfBook返回Promise,因此您需要使用函数then

调用该功能如下:

getTopOfBook().then((result) => {
  console.log("Result:" + result);
});

查看此代码段

let sleep = (fn) => {
  setTimeout(fn, 1000);
};
let getContractAddress = function(cb) {
  return new Promise((r) => sleep(() => {
    r('getContractAddress')
  }));
};
let getTokenBySymbolIfExistsAsync = function(str) {
  return new Promise((r) => sleep(() => {
    r({
      address: 'getTokenBySymbolIfExistsAsync: ' + str
    })
  }));
};
let WETH_ADDRESS = '';
let ZRX_ADDRESS = '';
let EXCHANGE_ADDRESS = '';
async function getTopOfBook() {
  var result = 'test getTopOfBook';
  const EXCHANGE_ADDRESS = await getContractAddress();
  const wethTokenInfo = await getTokenBySymbolIfExistsAsync('WETH');
  const zrxTokenInfo = await getTokenBySymbolIfExistsAsync('ZRX');
  if (wethTokenInfo === undefined || zrxTokenInfo === undefined) {
    return Promise.reject(new Error('could not find token info'));
  }
  const WETH_ADDRESS = wethTokenInfo.address;
  const ZRX_ADDRESS = zrxTokenInfo.address;
  console.log(WETH_ADDRESS);
  console.log(ZRX_ADDRESS);
  console.log(EXCHANGE_ADDRESS);
  return result;
}
var main = function() {
  console.log('Waiting response...');
  getTopOfBook().then((result) => {
    console.log("Result:" + result);
    console.log('DONE!');
  }).catch((error) => {
      console.log(error);
  });      
};
main();
.as-console-wrapper {
  max-height: 100% !important
}

如果要投掷错误,请使用函数Promise.reject()

  • 与该电话一起,您需要传递reject功能或调用catch函数。

在此示例中,我们正在传递reject函数:

(error) => {
    console.log(error); 
}

如果您不通过reject功能,则需要调用catch功能才能处理抛出错误。

let sleep = (fn) => {
  setTimeout(fn, 1000);
};
let getContractAddress = function(cb) {
  return new Promise((r) => sleep(() => {
    r('getContractAddress')
  }));
};
let getTokenBySymbolIfExistsAsync = function(str) {
  return new Promise((r) => sleep(() => {
    r()
  }));
};
let WETH_ADDRESS = '';
let ZRX_ADDRESS = '';
let EXCHANGE_ADDRESS = '';
async function getTopOfBook() {
  var result = 'test getTopOfBook';
  const EXCHANGE_ADDRESS = await getContractAddress();
  const wethTokenInfo = await getTokenBySymbolIfExistsAsync('WETH');
  const zrxTokenInfo = await getTokenBySymbolIfExistsAsync('ZRX');
  if (wethTokenInfo === undefined || zrxTokenInfo === undefined) {
    return Promise.reject('Could not find token info');
  }
  const WETH_ADDRESS = wethTokenInfo.address;
  const ZRX_ADDRESS = zrxTokenInfo.address;
  console.log(WETH_ADDRESS);
  console.log(ZRX_ADDRESS);
  console.log(EXCHANGE_ADDRESS);
  return result;
}
var main = function() {
  console.log('Waiting response...');
  getTopOfBook().then((result) => {
    console.log("Result:" + result);
    console.log('DONE!');
  }, (error) => {
    console.log(error); 
  }).catch((error) => {
    console.log(error); // This line will be called if reject function is missing.
  });
};
main();
.as-console-wrapper {
  max-height: 100% !important
}

资源

  • Promise.prototype.then()
  • Promise.reject()
  • 异步函数

调用异步功能时,它会返回承诺。当异步函数返回值时,将使用返回的值解决承诺。当异步函数抛出异常或某个值时,承诺将被抛弃的值拒绝。

最新更新