【问题标题】:Node.JS Async / Await Dealing With Callbacks? [duplicate]Node.JS 异步/等待处理回调? [复制]
【发布时间】:2018-01-02 10:43:14
【问题描述】:

除了混入 bluebird 或 return new Promise() 之外,有没有办法处理异步 function() 中的回调函数?

例子很有趣...

问题

async function bindClient () {
  client.bind(LDAP_USER, LDAP_PASS, (err) => {
    if (err) return log.fatal('LDAP Master Could Not Bind', err);
  });
}

解决方案

function bindClient () {
  return new Promise((resolve, reject) => {
    client.bind(LDAP_USER, LDAP_PASS, (err, bindInstance) => {
      if (err) {
        log.fatal('LDAP Master Could Not Bind', err);
        return reject(err);
      }
      return resolve(bindInstance);
    });
  });
}

有没有更优雅的解决方案?

【问题讨论】:

  • nodejs v.8.x.x util.promisify (:
  • 编写一个通用函数来为您调用new Promise。或者只使用现有的众多库之一,无论是来自节点的utilBluebird 还是任何其他库。
  • util.promisify 对象和函数的包装器:npmjs.com/package/doasync

标签: javascript node.js asynchronous


【解决方案1】:

NodeJS v.8.x.x 原生支持 Promisifying 和 async-await,所以是时候享受这些东西了(:

const 
  promisify = require('util').promisify,
  bindClient = promisify(client.bind);

let clientInstance; // defining variable in global scope
(async () => { // wrapping routine below to tell interpreter that it must pause (wait) for result
  try {
    clientInstance = await bindClient(LDAP_USER, LDAP_PASS);
  }
  catch(error) {
    console.log('LDAP Master Could Not Bind. Error:', error);
  }
})();

或者只是简单地使用co 包并等待异步等待的原生支持:

const co = require('co');
co(function*() { // wrapping routine below to tell interpreter that it must pause (wait) for result
  clientInstance = yield bindClient(LDAP_USER, LDAP_PASS);

  if (!clientInstance) {
    console.log('LDAP Master Could Not Bind');
  }
});

附: async-await 是生成器生成语言构造的语法糖。

【讨论】:

  • async / await 原生支持不带标志?
  • @kmgilbert100 当然不是。有2种方法:1.和谐标志,2.使用babel。问题是如何编写将回调转换为承诺的较短版本 - 最新节点做得很好。
  • 您正确回答了问题。但是 async / await 语法在 7 / 8 正式支持,没有标志 - node.green/#ES2017-features-async-functions
  • @kmgilbert100 太棒了! (:我不会将我的代码切换到异步等待的东西,直到它表现出良好的性能。现在我对 Promise 感到满意。
  • 迄今为止,我已经在几个生产应用程序中使用了它,并且表现良好! - 没有注意到任何问题......但请记住,节点现在会在未处理的拒绝时终止进程......所以如果您打算将异步函数与 express / etc 结合使用,请确保用 try/catch 包装它和一些特殊的错误处理:)
【解决方案2】:

使用模块!以pify 为例

const pify = require('pify');
async function bindClient () {
  let err = await pify(client.bind)(LDAP_USER, LDAP_PASS)
  if (err) return log.fatal('LDAP Master Could Not Bind', err);
}

还没有测试过

【讨论】:

    猜你喜欢
    • 2021-11-01
    • 2018-09-22
    • 2021-05-25
    • 2021-06-30
    • 1970-01-01
    • 2022-01-02
    • 2013-08-03
    • 1970-01-01
    相关资源
    最近更新 更多