2016-06-10 20 views
0

Ich bin neu zu versprechen und ich versuche, den Wert eines Versprechens wie Mungo wiederzugeben, aber mit Mongoskin und Bluebird. Dies funktioniert mit Mungo return User.find().then(users => users). Dies wird eine Liste von Benutzern zurückgeben, die in Apollo-Server-Resolvern kein Versprechen darstellen.Rückgabewert des Versprechens

Ich habe versucht, Generator und asynchronen Versprechen, aber ohne Glück. Von dem, was ich gelesen habe, gibt ein Versprechen immer ein Versprechen zurück, also keine Ahnung, wie Mungo einen Wert zurückgibt.

mongodb.js

import Promise from 'bluebird'; 
import mongoskin from 'mongoskin'; 

Object.keys(mongoskin).forEach(function (key) { 
    var value = mongoskin[key]; 
    if (typeof value === 'function') { 
    Promise.promisifyAll(value); 
    Promise.promisifyAll(value.prototype); 
    } 
}); 

Promise.promisifyAll(mongoskin); 

export default { 
    connect (uri) { 
    return mongoskin.db(uri, {native_parser:true}); 
    } 
}; 

users.js

import mongodb from '../../databases/mongodb'; 

export default class User { 
    constructor() { 
    this.db = mongodb.connect('mongodb://127.0.0.1:27017/test', {native_parser:true}); 
    this.collection = this.db.collection('users'); 
    } 

    find (query = {}, options = {}) { 
    const findAsync =() => { 
     return Promise.resolve().then(() => { 
     return this.collection.findAsync(query, options); 
    }) 
    .then((xx) => { 
     xx.toArray((err, items) => { 
     if (err) return err; 
     return items; 
     }); 
    }); 

    }; 

    async function getData() { 
     let foo = await findAsync(); 

     return foo; 
    } 

    return getData(); 
    } 
} 

const user = new User(); 

function bar() { 
    return user.find().then(x => console.log(x)); 
} 

console.log(bar()); 
+1

'User.find(). Then (users => users)' _does_ gibt ein Versprechen zurück. – robertklep

+0

Das könnte etwas mit der Tatsache sein, dass ich es mit Apollo-Server verwende. Ich werde die Frage bearbeiten – otissv

Antwort

2

Ihr Code scheint zu kompliziert. Ich denke, was Sie wollen, ist dies (ich nicht mongoskin promisify hat, weil es für das nicht sehr gut geeignet ist, siehe unten):

export default class User { 
    constructor() { 
    this.db   = mongoskin.connect(...); 
    this.collection = this.db.collection('users'); 
    } 

    find (query = {}, options = {}) { 
    return new Promise((resolve, reject) => { 
     this.collection.find(query, options).toArray((err, items) => { 
     if (err) return reject(err); 
     resolve(items); 
     }); 
    }); 
    } 
} 

Ich muss sagen, dass Mongoskin ziemlich veraltet anfühlt. Es ist ein Skin auf dem offiziellen mongodb Treiber, der heutzutage ziemlich anständig ist (er unterstützt zum Beispiel Versprechen, die Mongoskin nicht propagiert).

Wenn Sie promisify wollen, dann würde ich sagen, dass die folgende ist ein Versprechen, anti-Muster:

return Promise.resolve().then(() => { 
    return this.collection.findAsync(query, options); 
}).then(...) 

Sie können es neu schreiben, um diese:

return this.collection.findAsync(query, options).then(...); 

jedoch die toArray() macht die Sache wieder schwierig, weil Sie dafür brauchen, um ein neues Versprechen zu erstellen, so wird der Code etwa so:

return this.collection.findAsync(query, options).then((cursor) => { 
    return new Promise((resolve, reject) => { 
    cursor.toArray((err, items) => { 
     if (err) return reject(err); 
     resolve(items); 
    }); 
    }); 
}); 

Das sieht überhaupt nicht sehr hübsch aus, daher meine Entscheidung, nicht zu promistifizieren und nur Callbacks in diesem Fall zu verwenden (obwohl ich sicher bin, dass Bluebird einige nette Tools hat, die den obigen Code einfacher betrachten können, aber immer noch...).

+0

Vielen Dank für die Erklärung und die Vereinfachung meines Codes. Wird versuchen, den nativen Treiber zu verwenden. Ich denke, das könnte der Apollo-Server sein, der ein Versprechen akzeptiert, aber nicht zu erfüllen scheint, es sei denn, ich benutze Mungo und nicht so, wie ich es mache. Ich werde versuchen, in ihrem Kanal zu fragen. – otissv

Verwandte Themen