2016-07-23 12 views
-1

Ich habe einen Nodejs Express-Server und ich arbeite mit Bluebird Promises für die Synchronisierung aller asynchronen Sachen.Bluebird Versprechen Variable: 'undefined ist keine Funktion'

Alles funktioniert auf localhost eine AWS RDS MySQL-Datenbank, in Ordnung, aber wenn ich den Server auf meine AWS EC2-Instanz hochgeladen Ich habe ein Problem mit dieser Funktion gefunden:

var Promise = require('bluebird'); 
var db  = require('./db'); 

exports.matchValue = function (params) { 
    return new Promise(function(resolve, reject) { 
     var findValue = new Promise(); 
     if (params.find.includes(".")) { 
      var aux = params.find.split("."); 
      var matchBy = {}; 
      if (aux[0]) matchBy.a = aux[0]; 
      if (aux[1]) matchBy.b = aux[1]; 
      findValue = db.getValues1(params.limit,params.page,matchBy); 
     } 
     else { 
      findValue = db.getValues2(params.limit,params.page,params.find); 
     } 
     findValue 
     .then(function(result) { 
      resolve(result); 
     }) 
     .catch(function(err) { 
      reject(err); 
     }); 
    }); 
} 

ich die Variable findvalue erklärt haben, als neues Versprechen, da es abhängig von der if-Bedingung den Wert einer anderen Datenbankabfragefunktion erhält (diese Funktionen geben ein Promise zurück).

Wenn ich diese Funktion aufrufen, ist das das Ergebnis: "undefined ist keine Funktion".

Ich verstehe, dass dieses Verhalten passiert, weil es zuerst findValue.then() als if/else Blockcode ausführt, und da die Variable nicht definiert ist, kann es eine Funktion sein.

Ich dachte, dass eine Variable als eine neue Promise deklarieren wird es warten wird, bis die Rückgabe der dieser Variablen zugewiesenen Funktion beendet wird, aber tatsächlich nicht geschieht.

Was mache ich falsch? Kann mir jemand helfen?

Danke in Beratung !!

+0

** Woher **, genau, erhalten Sie den Fehler? –

+0

Was ist "params.find"? Weil Sie 'params.find.includes' verwenden, das, wenn' params.find' ein Array ist, relativ neu ist und nicht auf älteren JavaScript-Engines existiert. –

+0

Ich bekomme den Fehler auf '.then (Funktion (Ergebnis)' und es passiert nur, wenn der Knoten auf einer EC2-Instanz ausgeführt wird, wenn es auf localhost ausgeführt wird, Ergebnis enthält die Abfrageantwort und params.find ist nur eine Zeichenfolge. Danke. " – javing

Antwort

-1

Ihre .matchValue() Funktion sollte vereinfachen:

exports.matchValue = function(params) { 
    var aux = params.find.split('.'); 
    return (aux.length < 2) ? db.getValues2(params.limit, params.page, params.find) : db.getValues1(params.limit, params.page, { 'a': aux[0], 'b': aux[1] }); 
}; 

Mit diesem wird .then(function(result) sicherlich nicht werfen, weil diese Zeile verschwunden ist, aber der Anrufer der Funktion könnte stattdessen gut werfen. Wenn ja, dann müssen Sie (wieder) vermuten, dass entweder db.getValues1() oder db.getValues2() keine Versprechen auf dem EC2-Server zurückgibt; Versuchen Sie, den zurückgegebenen Wert/Objekt zu protokollieren, um zu sehen, was es ist.

+0

Ich habe das if/else entfernt, und etwas ähnliches wie Ihre Antwort (Rückgabe des Ergebnisses der db-Funktionen zu findValue und findValue.then (Ergebnis)) funktioniert es gut, danke! – javing

+0

Cool, obwohl es ein Rätsel ist, was das Problem war und was genau es behoben hat. –

0

Ich habe die Variable findValue als neues Versprechen deklariert, da sie abhängig von der if-Bedingung den Wert einer anderen Datenbankabfragefunktion erhält (diese Funktion gibt eine Promise zurück).

In JavaScript deklarieren Sie keine Variablen als einen beliebigen Typ. Diese Zeile:

var findValue = new Promise(); 

deklariert eine Variable (var findValue) und versucht, ein Versprechen (= new Promise()) zu erstellen. Der Promise Konstruktor erfordert, dass Sie eine Funktion übergeben. Es versucht, sein erstes Argument als eine Funktion zu verwenden, und da Sie es keine Argumente übergeben haben, erhält es undefined für das erste Argument   — daher der Fehler.

Sie konnte es nur zu

ändern
var findValue; 

... aber Ihr Code zum Opfer zu fallen die unnötige Versprechen Schöpfung Trugschluss: Nur das Versprechen verwenden Sie bereits haben:

exports.matchValue = function (params) { 
    var findValue; 
    if (params.find.includes(".")) { 
     var aux = params.find.split("."); 
     var matchBy = {}; 
     if (aux[0]) matchBy.a = aux[0]; 
     if (aux[1]) matchBy.b = aux[1]; 
     findValue = db.getValues1(params.limit,params.page,matchBy); 
    } 
    else { 
     findValue = db.getValues2(params.limit,params.page,params.find); 
    } 
    return findValue; 
} 
+0

Danke für Ihre Antwort T.J. Crowder, aber das war das erste was ich getestet habe und funktioniert auch nicht! Es gibt die gleiche Nachricht – javing

+0

@javing: Dann müssen Sie die Frage klären. Genauer gesagt, von welcher genauen Zeile erhalten Sie den Fehler? –

+0

Es sieht so aus, als sei seine 'db' nicht promitiert, und' findValue' wird einfach'undefiniert'. – Bergi

0

Angenommen, Ihre db.getValues1/db.getValues2 Funktionen versprechen Rückkehr (sie erscheinen nicht einen Rückruf zu nehmen, und ich weigere ich zu übernehmen Sie einen synchronen DB-Treiber in der Produktion verwenden), versuchen Sie die folgende Version Ihres gepostet Code:

var Promise = require('bluebird'); 
var db  = require('./db'); 

exports.matchValue = function (params) { 
    var findValue; 

    if (params.find.includes(".")) { 
     var aux = params.find.split("."); 
     var matchBy = {}; 
     if (aux[0]) matchBy.a = aux[0]; 
     if (aux[1]) matchBy.b = aux[1]; 
     findValue = db.getValues1(params.limit,params.page,matchBy); 
    } 
    else { 
     findValue = db.getValues2(params.limit,params.page,params.find); 
    } 

    return findValue; 
} 

Wenn es funktioniert, großartig. Hier sind einige Dinge zu beachten:

  1. Sie erstellen ein neues Versprechen. Tu das nicht. Verleihen Sie Standard-Node-konformen Funktionen/Bibliotheken, die die Routinen promisification von Bluebird verwenden.

  2. Bluebird 2.x und 3.x werfen auf var findValue = new Promise(). Wie bereits erwähnt, benötigt der Konstruktor eine Funktion als Argument. Ich vermute, Sie haben die Fehlermeldung, die Sie tatsächlich erhalten, paraphrasiert. Wenn ja, tu das nicht, es macht es sehr schwierig für andere herauszufinden, was falsch ist.

  3. Wenn Sie das nächste Mal auf SO veröffentlichen, reduzieren Sie bitte Ihren Beispielcode auf etwas, das jeder ausführen und Ihr Problem problemlos reproduzieren kann. Sie können im Laufe der kleinsten Repro finden, dass Sie Ihr eigenes Problem lösen. Wenn Sie das nicht tun, können die Leute hier effektiver helfen.