2016-04-20 11 views
0

Vielleicht verstehe ich nicht die Art und Weise Promise.promisifyAll funktioniert. Ich versuche, coinbase Paket zu promitifizieren.Bluebird promisifyAlle nicht erstellen ganze Reihe von Async-Funktionen

Grundsätzlich werden die Funktionen des Clients zugesagt, aber die von diesen Funktionen zurückgegebenen Konten scheinen nicht die Async Version: [TypeError: acc.getTransactionsAsync is not a function] zu haben.

Ich habe versucht, {multiArgs:true} als Optionen zu Promise.promisifyAll() wie in an answer to a similar question vorgeschlagen, aber es hat das Problem nicht gelöst. Jeder Vorschlag wird geschätzt.

Normalweg das Paket der Verwendung (Werke):

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 Version funktioniert nicht (getTransactionsAsync nicht definiert ist, aber die getAccountsAsync kehrt die Konten korrekt):

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

EDIT:

Blick durch das Paket möchte ich versprechen, realisierte ich, dass die Funktion Anweisungen, die ich aufrufen möchte, stammen von den Modellobjekten, die vom Paket zurückgegeben werden. Ich denke, promisifyAll analysiert nur die Clientfunktionen, und die Modelle werden nicht verarbeitet. Ich bin einfach nicht so gut auskennen, wie die Analyse gemacht :(

Das sind die index.js ist (Modul exportiert)

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

EDIT 2:

Der Kunde es verlangt Eigene Modell-Module, also Promise.promisifyAll sollten wie erwartet mit den Eigenschaften des Objekts ohne vorhergehende Bearbeitung interferieren.An dieser Stelle denke ich, dass es keine andere Möglichkeit geben könnte, meine eigenen Versprechungen für alle Funktionen zu machen, die ich nicht direkt unter der leben will Client

+0

Ich versuche zu vermeiden, viele 'neue Promise (...)' Funktionen zu erstellen, aber ich kann keine andere Möglichkeit finden, dieses Problem zu lösen. – Fdo

Antwort

3

Ich denke promisifyAll nur die Client-Funktionen analysiert, und die Modelle werden nicht verarbeitet werden.

Nicht genau. Das hat nichts damit zu tun, wie promisifyAll die Methoden und Eigenschaften durchsucht.Vielmehr werden Sie explizit nur die Client-Methoden vorbei zu promisified werden:

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

Es gibt keinen Link von client zu den Modellen. Vielmehr versuchen promisifyAll auf das gesamte Modul zu nennen, nicht nur die Client Klasse:

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

oder wenn das nicht funktioniert, Anruf promisifyAll sowohl auf der Client Klasse und die models Sammlung von Klassen:

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

Das hat auch nicht funktioniert, es war die ursprüngliche Art, wie ich telefonierte. Nach einer Antwort/einem Vorschlag änderte ich es auf diese Weise, aber er löschte seine Antwort und ich denke, er war derjenige, der meine Frage abgelehnt hat. Innerhalb des Clients werden die Modelle als Eigenschaften benötigt, daher sollten sie promitiert werden (aber nicht), siehe ** EDIT 2 **. Ich wollte keine andere große Datei kopieren und einfügen, die Frage ist schon zu lang. – Fdo

+0

Nein, nur weil die Datei 'client.js' einige der' modules/...' Dateien benötigt, heißt das nicht, dass sie promitifiziert werden. Es werden nur Klassen promitiert, die als * Eigenschaften * vom 'Client' oder' Client.prototype' erreichbar sind. – Bergi

+0

Oh, richtig, 'promisifyAll' zieht es nicht in Betracht, tiefer in' coinbase.models' zu gehen, weil es keine Klasse ist (kein Großbuchstabe, etc). – Bergi

0

Also, anstatt die Frage erneut zu bearbeiten, füge ich meine temporäre Workaround (mit einem etwas anderen Funktionsaufruf, aber das hatte das gleiche Problem, nicht die Async Funktion). Dies macht die Modellmodule für sich selbst attraktiv, und ich muss sie auf Anforderung erstellen, wenn ich eine Promistified-Funktion für die nicht promitierte Version der vom Client zurückgegebenen Modelle benötige.

Es ist nicht, was ich tun möchte, da mehr Speicherzuweisung für jedes Modell benötigt wird, das ich einen promisified Funktionsaufruf machen möchte. Aber ich bevorzuge diesen Ansatz gegenüber dem Erstellen neuer Module zum Gruppieren von new Promise(...) Funktionen.

Wenn eine bessere Lösung vorgeschlagen wird, werde ich dies immer noch als gelöst markieren.

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