2

I would like to have a nice and simple layer over a mongodb instance using dart, and I cannot manage to do it :

Given a mongodb instance "test-mongo-layer" :

mongo shell :

use test-mongo-layer switched to db test-mongo-layer db.users.find() { "_id" : ObjectId("524b1bf8fbfe21c9c4cdb772"), "name" : "Toto", "login" : "toto" } { "_id" : ObjectId("524b1bf8fbfe21c9c4cdb772"), "name" : "Titi", "login" : "titi" }

And a model.dart source file :

class User {
  String name;
  String login;

  User(this.name, this.login)

  User.fromJson(Map map) {
    name  = map['name'];
    login = map['login'];
  }
}

And a persistence.dart source file :

import 'package:mongo_dart/mongo_dart.dart';
import '../lib/model.dart';

class PersistenceLayer{

  Db _mongodb;

  PersistenceLayer(this._mongodb)

  List<User> getUsers() {

    List<User> users = new List();

    _mongodb.open().then((o){

      return __mongodb.collection('users').find().forEach((jsonUser){
        User user = new User.fromJson(jsonUser);
        users.add(user);  
      });

    }).then((jsonUsers){

      _mongodb.close();

    });

    return users;
  }

}

When I launch the following test :

import 'package:mongo_dart/mongo_dart.dart';
import 'package:unittest/unittest.dart';
import '../lib/model.dart' ;
import '../lib/persistence.dart' ;
main() {

  Db db = new Db("mongodb://127.0.0.1/test-mongo-layer");

  test('Test get users', () {

      PersistenceLayer persistence = new PersistenceLayer(db);
      var users = persistence.getUsers();
      expect(users.length, 2);
  }

}

Then a got an exception :

Uncaught Error: Expected: <2> Actual: <0><

This is quite simple but it's not working, i must mess with the Future because the code is not even executed when I execute it on debug...

SOLUTION : thanks to Alexandre

persistence.dart source file :

  Future<List<User>> getUsers() {
    List<User> users = new List();
    return _mongodb.open()
                .then((_){
                    return _mongodb.collection('users').find().forEach((jsonUser){
                       User user = new User.fromJson(jsonUser);
                       users.add(user);
                       });
                })
               .then((_) {
                    return users;
                })
                .whenComplete((){
                    _mongodb.close();
                });
   }

test :

test('Test get users', () {
      PersistenceLayer persitence = new MongoPersistence(db);
      Future<List<User>> usersFuture = persistence.getUsers();
      usersFuture.then((users) => expect(users.length, 2)   );
});
4

1 に答える 1

0

で同期コードと非同期コードを混在させていますgetUsers。返却users後、充填を行います。それが空であるgetUsers()理由です。users

コードをよりよく理解し、非同期にするために、 The Event Loop と DartFutureを見ることができます。

の動作バージョンはgetUsers()次のようになります (テストされていません)。

import 'dart:async';
import 'package:mongo_dart/mongo_dart.dart';
import '../lib/model.dart';

class PersistenceLayer{
  Db _mongodb;

  PersistenceLayer(this._mongodb)

  Future<List<User>> getUsers() {
    List<User> users = new List();
    return _mongodb.open().then((_){
      _mongodb.collection('users').find().forEach((jsonUser){
        User user = new User.fromJson(jsonUser);
        users.add(user);
      });
    }).whenComplete((_){
      _mongodb.close();
    }).then((_) => users);
  }
}

基本的に、Futureチェーン全体を返し、最後thenに を返しusersます。

于 2013-10-02T08:52:43.017 に答える