2016-01-21 3 views
1

У меня возникают проблемы с асинхронным выполнением в NodeJS. В частности, у меня много вариантов использования, когда я хочу использовать результат асинхронного запроса намного позже в своем коде и не хочу обертывать все это на другом уровне отступов, например, async.parallel.Использование обещаний для возврата результата асинхронной функции как «переменной»

Я понимаю, что решение этой проблемы использует обещания, но я изо всех сил пытаюсь получить право на реализацию, и ресурсы, которые я пытался, не помогают.

Моя текущая проблема заключается в следующем: Мне нужно получить _id документа MongoDB сразу же после его установки. Я переключился с использования MongoJS на использование официального драйвера MongoDB, поскольку мне стало известно, что MongoJS не поддерживает обещания. Может ли кто-нибудь помочь, предоставив базовый пример того, как вернуть это значение, используя обещания?

Еще раз спасибо.

ответ

1

С Node.js водителем, используйте метод insert() в коллекции, которая возвращает Обещание. Следующий пример демонстрирует это:

var Db = require('mongodb').Db, 
    MongoClient = require('mongodb').MongoClient, 
    Server = require('mongodb').Server; 

var db = new Db('test', new Server('localhost', 27017)); 

// Fetch a collection to insert document into 
db.open(function(err, db) { 
    var collection = db.collection("post"); 

    // Create a function to return a promise 
    function getPostPromise(post){ 
     return collection.insert(post); 
    } 

    // Create post to insert 
    var post = { "title": "This is a test" }, 
     promise = getPostPromise(post); // Get the promise by calling the function 

    // Use the promise to log the _id 
    promise.then(function(posts){ 
     console.log("Post added with _id " + posts[0]._id);  
    }).error(function(error){ 
     console.log(error); 
    }).finally(function() { 
     db.close(); 
    }); 
}); 

Вы также можете использовать save() метод Mongoose как он возвращает Promise. Основной пример, чтобы продемонстрировать это следующим образом:

// test.js 
var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

// Establish a connection 
mongoose.connect('mongodb://localhost/test', function(err) { 
    if (err) { console.log(err) } 
}); 

var postSchema = new Schema({ 
    "title": String 
}); 

mongoose.model('Post', postSchema); 

var Post = mongoose.model('Post'); 

function getPostPromise(postTitle){ 
    var p = new Post(); 
    p.title = postTitle; 
    return p.save(); 
} 

var promise = getPostPromise("This is a test"); 
promise.then(function(post){ 
    console.log("Post added with _id " + post._id); 
}).error(function(error){ 
    console.log(error); 
}); 

Запустите приложение

$ node test.js 
Post added with _id 5696db8a049c1bb2ecaaa10f 
$ 
+1

. Этот первый пример был абсолютно идеальным. Благодаря! – Nodal

+1

@Nodal Не беспокойтесь, рад помочь :) – chridam

+0

Привет, в первом примере я получаю сообщение об ошибке «TypeError: prom.then (...). Ошибка не является функцией». Я не смог найти много информации об этой ошибке, но я предполагаю, что мне либо недостает модуля, необходимого для использования обещаний, либо обещания в Mongodb, не поддерживающие '.error'? Или что-то еще, конечно. – Nodal

1

Ну, вы можете использовать традиционный подход с Promise.then(), или если вы можете использовать ES6, попробуйте функции генератора (генераторы включены непосредственно в Node, не требуется флаг времени выполнения). Таким образом, вы могли бы просто написать этот код:

//You can use yield only in generator functions 
function*() { 
    const newDocument = new Document({firstArg, SecondArg}); 
    const savedDocument = yield newDocument.save(); 
    //savedDocument contains the response from MongoDB 

}

Вы можете прочитать больше о функции * here

+0

я действительно в состоянии использовать ES6. Это выглядит многообещающим (каламбур не предназначен!). Я собираюсь пойти с этим выстрелом и вернуться к вам, может быть, завтра, поскольку у меня мало времени, и бесчисленные вещи неизбежно пойдет не так. Еще раз спасибо! – Nodal

+1

Хорошо, теперь я вижу, что забыл упомянуть, что мой примерный код зависит от Mongoose, но он почти такой же, как и чистое решение => просто дает Promise – yunicz

Смежные вопросы