javascript - 使带有回调/ promise 实现的 javascript 函数始终返回 promise

标签 javascript node.js asynchronous promise bluebird

我正在尝试拥有一个异步身份验证处理程序,它可以具有回调或 promise 的实现。范围是包装此函数以便始终返回 promise ,因此我可以进一步使用它,与回调/ promise 无关。

如果有人能为这些场景提供一些帮助,我将不胜感激,其中一个例子就是现实生活。

如果函数类似于:

function getData(id, callback) {
  var deferred = Q.defer();
  apiCall('/path/to/id', function (err, data) {
    if (err) deferred.reject(new Error(err));
    //do something with data
    deferred.resolve(processedData);
  }
  deferred.promise.nodeify(callback);
  return deferred.promise;
}

我想以这种方式使用 .fromCallback

function myProcessedDataFunction(id) {
  return Promise.fromCallback(function (callback) {
    return getData(id, callback);
  }, {multiArgs: true});
}

这行得通吗? myProcessedDataFunction 会返回正确的 promise 吗?

现实世界的例子是:

我有一个身份验证处理程序,它可能会也可能不会使用回调函数来实现,同时可以使用 Promise 来实现;或者它可能返回一个真/假值;

function authHandlerImplementation1(username, password) { 
  return (username === 'validUsername' && password === 'validPassword');
}

function authHandlerImplementation2(username, password, callback) {
  apiCall('/path/to/authorization', function (err, result) {
    if (err) return callback(err, null);
    callback(null, result);
  });
}

function authHandlerImplementation3(username, password) {
  return new Promise(function (reject, resolve) {
    apiCall('/path/to/authorization', function (err, result) { 
      if (err) return reject(err);
      resove(result);
    });
  });
}

function authHandlerImplementation4(username, password, callback) { 
  var deferred = Q.defer();
  apiCall('/path/to/id', function (err, data) {
    if (err) deferred.reject(new Error(err));
    //do something with data
    deferred.resolve(processedData);
  }
  deferred.promise.nodeify(callback);
  return deferred.promise;
}

我将尝试使用 bluebird 实现第五个。

function authHandlerImplementation5(username, password, callback) { 
  return apiCall('/path/to/id', callback).asCallback(callback); // I hope this is the right way to do it (correct me if I'm wrong, please)
}

我的 checkAuth 函数使用 authHandler 实现,并且希望与回调/ promise 无关。

function checkAuth(username, password) { 
  var self = this;
  return Promise.fromCallback(function(callback) { 
    return self.authHandler(username, password, callback); 
  }, {multiArgs: true});
}

如果 authHandlerImplementation 不使用回调(仅返回一个值)(implementation1),则 checkAuth 挂起,什么也没有发生,我的测试失败。

是否有 Bluebird 方法可以将任何类型的 authHandler 实现包装到 Promise 中(无论是简单的返回、回调还是 Promise 实现)?

最佳答案

不,Bluebird 没有这样的实用程序。如果您将回调和 Promise 作为 API 提供,那么同时支持回调和 Promise 是很好的选择,但当您需要使用 API 时,则不然——从外部区分该方法是采用回调还是返回 Promise 或两者都无法实现,并且需要编写动态计算出来的代码(在每次通话中)可能是可能的,但很尴尬。

Bluebird 确实有一个实用程序来包装可能返回、抛出或返回 promise 的函数,它被称为 Promise.method (还有 Promise.try 立即调用它)。

如果您的调用者想要传递异步身份验证处理程序,我建议强制您的调用者使用 promise 。如果他们只有一个基于回调的回调,他们仍然可以将其包装在 Promise.promisify 中。在将其提供给您之前自行处理。

关于javascript - 使带有回调/ promise 实现的 javascript 函数始终返回 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39851023/

相关文章:

node.js - Ansible 无法运行全局 npm 包

javascript - 如何创建 Json 数组

JavaScript 无法设置变量 – FancyInput 示例

javascript - 预期数组但收到...(JSON)... AngularJS 错误

javascript - 我可以取消 promise 的执行吗?尝试检查数千个链接并且不想等待请求超时

c# - 带有可取消 EventArgs 的 INotifyPropertyChanging EventHandler 中的异步/等待

c# - webapi 2 - 如何在新线程中正确调用长时间运行的异步方法,并将响应返回给客户端

python-3.x - 如何从dramatiq python获取处理后的结果?

javascript - 从 DOM 数组中移除 DOM 对象

javascript - 从/到 Javascript 字符串从 Go int64/uint64 序列化反序列化