Bluebird promisifyAll不会创建整个异步函数集

Bluebird promisifyAll not creating entire set of Async functions

本文关键字:异步 函数 创建 promisifyAll Bluebird      更新时间:2023-09-26

也许我不了解Promise.promisifyAll的工作方式。我正在尝试承诺coinbase包。

基本上,客户端的函数是承诺的,但这些函数返回的帐户似乎没有Async版本:[TypeError: acc.getTransactionsAsync is not a function]

我曾尝试将{multiArgs:true}作为选项传递给Promise.promisifyAll(),正如在回答类似问题时所建议的那样,但它并没有解决问题。欢迎提出任何建议。

使用包(作品)的正常方式:

var Client = require('coinbase').Client
var client = new Client({
  'apiKey': '<snip>',
  'apiSecret': '<snip>',
  'baseApiUri': 'https://api.sandbox.coinbase.com/v2/',
  'tokenUri': 'https://api.sandbox.coinbase.com/oauth/token'
});
//Callbacks
client.getAccounts({}, function(err, accounts) {
  accounts.forEach(function(acc) {
    acc.getTransactions(null, function(err, txns) {
      txns.forEach(function(txn) {
        console.log('txn: ' + txn.id);
      });
    });
  });
});

承诺版本不起作用(getTransactionsAsync未定义,但getAccountsAsync正确返回帐户):

var Promise = require('bluebird');
var Client = require('coinbase').Client;
var client = new Client({
  'apiKey': '<snip>',
  'apiSecret': '<snip>',
  'baseApiUri': 'https://api.sandbox.coinbase.com/v2/',
  'tokenUri': 'https://api.sandbox.coinbase.com/oauth/token'
});
Promise.promisifyAll(client);
//Promises
client.getAccountsAsync({}) //Works perfectly, returns the accounts
.then(function(accounts) {
  return Promise.map(accounts, function(acc) {
    return acc.getTransactionsAsync(null); //This function call is throwing the TypeError
  });
})
.then(function(transactions) {
  console.log('Transactions:');
  transactions.forEach(function(tx) {
    console.log(tx);
  });
})
.catch(function(err) {
  console.log(err);
});

编辑:

通过查看我想要promisify的包,我意识到我试图调用的函数来自包返回的模型对象。我认为promisifyAll只解析客户端函数,模型没有被处理。我只是不太熟悉解析是如何进行的:(

这是index.js(模块导出)

var Account       = require('./lib/model/Account.js'),
    Address       = require('./lib/model/Address.js'),
    Buy           = require('./lib/model/Buy.js'),
    Checkout      = require('./lib/model/Checkout.js'),
    Client        = require('./lib/Client.js'),
    Deposit       = require('./lib/model/Deposit.js'),
    Merchant      = require('./lib/model/Merchant.js'),
    Notification  = require('./lib/model/Notification.js'),
    Order         = require('./lib/model/Order.js'),
    PaymentMethod = require('./lib/model/PaymentMethod.js'),
    Sell          = require('./lib/model/Sell.js'),
    Transaction   = require('./lib/model/Transaction.js'),
    User          = require('./lib/model/User.js'),
    Withdrawal    = require('./lib/model/Withdrawal.js');
var model = {
  'Account'       : Account,
  'Address'       : Address,
  'Buy'           : Buy,
  'Checkout'      : Checkout,
  'Deposit'       : Deposit,
  'Merchant'      : Merchant,
  'Notification'  : Notification,
  'Order'         : Order,
  'PaymentMethod' : PaymentMethod,
  'Sell'          : Sell,
  'Transaction'   : Transaction,
  'User'          : User,
  'Withdrawal'    : Withdrawal
};
module.exports = {
  'Client' : Client,
  'model'  : model
};

编辑2:

客户端需要它自己的模型模块,因此Promise.promisifyAll应该像预期的那样具有对象的属性,而不会受到先前编辑的干扰。在这一点上,我认为可能没有其他选择,那就是为我需要的所有功能做出自己的承诺,而这些功能不是直接位于客户之下。

我认为promisifyAll只解析客户端函数,模型没有被处理。

不完全是。这与promisifyAll如何查看方法和属性无关。相反,您只显式地传递要承诺的客户端方法:

var Client = require('coinbase').Client;
var client = new Client(…);
Promise.promisifyAll(client);

client与模型之间没有链接 相反,尝试在整个模块上调用promisifyAll,而不仅仅是Client类:

var Client = Promise.promisifyAll(require('coinbase')).Client;

或者,如果不起作用,在Client类和models类集合上调用promisifyAll

var coinbase = require('coinbase');
var Client = Promise.promisifyAll(coinbase.Client);
Promise.promisifyAll(coinbase.model);

因此,我没有再次编辑这个问题,而是添加了我的临时解决方法(使用略有不同的函数调用,但没有Async函数的问题相同)。这通过自己的方式承诺了模型模块,每当我需要在客户端返回的模型的非承诺版本上使用承诺函数时,我都需要根据需要创建它们。

这不是我想做的,因为对于我想要进行承诺函数调用的每个模型,都需要更多的内存分配。但我更喜欢这种方法,而不是创建用于对new Promise(...)函数进行分组的新模块。

如果有人提出更好的解决方案,我仍然会将其标记为已解决。

var Promise = require('bluebird');
var Client = require('coinbase').Client;
var cbModel = require('coinbase').model;
var client = new Client({
  'apiKey': '<snip>',
  'apiSecret': '<snip>',
  'baseApiUri': 'https://api.sandbox.coinbase.com/v2/',
  'tokenUri': 'https://api.sandbox.coinbase.com/oauth/token'
});
Promise.promisifyAll(client);
Promise.promisifyAll(cbModel);
//Promises
client.getAccountAsync('primary')
.then(function(account) {
  account = new cbModel.Account(client, account);
  return account.getTransactionsAsync(null);
})
.then(function(transactions) {
  console.log('Transactions:');
  transactions.forEach(function(tx) {
    console.log(tx.id);
  });
})
.catch(function(err) {
  console.log(err);
});