0

仕組みを理解していないのかもしれませんPromise.promisifyAllCoinbaseパッケージを約束しようとしています。

基本的に、クライアントの関数は約束されていますが、それらの関数によって返されるアカウントには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);
      });
    });
  });
});

Promisified バージョンが機能しない (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);
});

編集:

約束したいパッケージを調べてみると、呼び出そうとしている関数は、パッケージによって返されたモデル オブジェクトからのものであることがわかりました。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、以前の編集が干渉することなく、オブジェクトのプロパティで期待どおりに動作する必要があります。この時点で、クライアントの直下に存在しない、必要なすべての関数に対して独自の Promise を作成するという選択肢は他にないと思います。

4

2 に答える 2

3

promisifyAllクライアント関数のみを解析し、モデルは処理されていないと思います。

ではない正確に。promisifyAllこれは、メソッドとプロパティを調べる方法とは関係ありません。むしろ、約束されるクライアントメソッドのみを明示的に渡しています。

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

clientモデルへのリンクはありません。クラスだけでなく、モジュール全体を呼び出すようにしてください。promisifyAllClient

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

または、それが機能しない場合は、クラスとクラスのコレクションのpromisifyAll両方を呼び出します。Clientmodels

var coinbase = require('coinbase');
var Client = Promise.promisifyAll(coinbase.Client);
Promise.promisifyAll(coinbase.model);
于 2016-04-20T11:11:32.230 に答える
0

そのため、質問を再度編集する代わりに、一時的な回避策を追加しています(関数呼び出しはわずかに異なりますが、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);
});
于 2016-04-20T11:03:37.377 に答える