Node.JS异步/等待如何处理回调?

5

除了混入bluebird或return new Promise()之外,有没有其他方法来处理async函数中的回调函数?

例子很有趣......

问题

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

有更优雅的解决方案吗?

2
Node.js v8.x.x中的util.promisify函数: - num8er
1
编写一个通用函数,为您执行 new Promise 调用。或者只需使用现有的许多函数之一,例如来自 node 的 utilBluebird 或任何其他库。 - Bergi
util.promisify 对象和函数的包装器:https://www.npmjs.com/package/doasync - Do Async
2个回答

9

NodeJS v.8.x.x原生支持Promise和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是用于生成器yield语言构造的语法糖。


async/await是否原生支持,无需使用标志? - kevingilbert100
@kmgilbert100 当然不是。有两种方法:1. 使用harmony标志,2. 使用babel。问题是如何编写将回调转换为Promise的较短版本 - 最新的Node已经很好地解决了这个问题。 - num8er
你回答问题是正确的。但是 async/await 语法在 Node.js 7/8 中已经被官方支持,无需使用标志 - http://node.green/#ES2017-features-async-functions - kevingilbert100
@kmgilbert100 太棒了!(: 在它展示出良好的性能之前,我不会将我的代码切换到async await。目前我对promises感到舒适。 - num8er
我已经在几个生产应用程序中使用它,目前表现良好!没有注意到任何问题...但请记住,Node现在会在未处理的拒绝时终止进程...因此,如果您计划将异步函数与express /等组合使用,请确保用try/catch包装它并进行一些特殊的错误处理 :) - kevingilbert100
显示剩余4条评论

-2

使用模块!例如{{link1: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);
}

还没有测试过


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接