Ooof. Haben Sie jemals einen dieser Tage, an denen Sie wissen, dass Sie in der Nähe sind, aber Sie können es nicht ganz bekommen?Ausführen einer variablen Anzahl von Mongo-Abfragen im Knoten, Rückgabe eines einzelnen Ergebnisses
Ich schreibe einen Henker Puzzle-Löser. Dies wird in einem Dienst ausgeführt, der mit Knoten/hapi geschrieben wurde, die mit mongo db gesichert sind.
So habe ich eine Funktion:
solvePuzzle(puzzle, alreadyCalled);
Die args sind das Rätsel selbst, mit gelösten Buchstaben als Literale und ungelöst wie s, etwa so:?
?O?N? ?O ?H? ?TO??
und alreadyCalled einfach sein eine Liste von Buchstaben genannt, aber falsch. Nach einiger Muckerei wird für jedes Wort ein RegEx erstellt, der dann an eine Funktion gesendet wird, die eine in mongo gespeicherte Wortliste nach Übereinstimmungen abfragt.
Alles funktioniert wie es sollte, und wenn ich eine Dummy-Wortliste als ein einfaches Array erstellen, funktioniert alles gut und ich bekomme eine Liste der Übereinstimmungen.
Die Rückkehr-Format ist ein Array von Objekten wie folgt: (I Array-Indizes verwenden Wortfolge zu erhalten, wenn mögliche Lösungen Anzeigen)
matches[0][?O?N?] = ['GOING', 'DOING', 'BOING'];
So auf das eigentliche Problem. Ich teile das ganze Puzzle in Worte auf und führe eine for-Schleife über sie aus, indem ich die Funktion aufruft, die die Mongo-Abfrage für jeden durchführt. Problem ist, dass der Funktionsaufruf scheinbar zurückkehrt, bevor die Abfrage tatsächlich ausgeführt wurde. Die Konsolenprotokolle, die durchsetzt sind, scheinen diese Theorie auszudrücken.
Ich habe versucht, die Abfragefunktion eine Verheißung zurückgeben, aber das hat nur dazu gedient, die Gewässer weiter zu verdrücken. Ich fühle mich wie ich bin schließen aber ja - ich weiß nicht. Hier war mein ursprünglicher nicht-Versprechen Code:
function solvePuzzle(puzzle, called) {
// first build the exclusion match pattern
//console.log('solvePuzzle: building match pattern');
var x = buildMatchPattern(puzzle, called);
// split the puzzle into words
//console.log('solvePuzzle: tokenizing puzzle');
var words = tokenize(puzzle.toUpperCase());
//console.log('solvePuzzle:', words);
var results = [];
for(var i = 0; i < words.length; i++) {
console.log('solvePuzzle: matching ' + words[i]);
results[i] = {};
results[i][words[i]] = matchWord(words[i], x);
}
console.log('solvePuzzle: matches: ', results);
return results;
}
function matchWord(word, exclude) {
var pattern = '^';
var letters = word.toUpperCase().split('');
var matches = new Array();
var query = {};
//console.log('matchWord:', letters);
for(var i = 0; i < letters.length; i++) {
if(letters[i] !== '?') {
pattern += letters[i];
}
else {
pattern += exclude;
}
}
pattern += '$';
var re = new RegExp(pattern);
//console.log('matchWord:', re);
query.word = {"$regex" : re, "$options": "i"};
//console.log("matchWord query:", JSON.stringify(query));
db.wordlist.find(query, function (err, words) {
if(err) {
console.error('error:', err);
}
for(let i = 0; i < words.length; i++) {
if(words[i] !== null) {
console.log('loop:', words[i].word);
matches.push(words[i].word);
}
}
console.log('matchWord:', matches.length);
if(matches.length < 1) {
console.log('matchWord: found no matches');
matches.push('No Matches Found');
}
return matches;
});
}
Also meine Konsolenausgabe war im Grunde:
solvePuzzle: matching ?O?N?
solvePuzzle: matches: [] <---- problem
loop: 'going'
loop: 'doing'
etc etc.
.
.
matchWord: 5 (number of matches found);
So wie Sie sehen können, wird der Anruf zu Matchwort zurückkehrt, bevor die eigentliche Abfrage ausgeführt wird. Also habe ich noch nie einen Hapi-Service gemacht, der von Mongo unterstützt wird. Wie kann ich diesen Code so strukturieren, dass er alle Wörter durchläuft, jedes einzelne Mongo abfragt und als Ergebnis ein einzelnes Array zurückgibt?
TIA.
siehe mein Update! – felix