Here I’m showing an example of converting MongoDB node driver into “synchronous” APIs from callback based asynchronous APIs.
We define two new classes to wrap up the native Db and Cursor. Two methods are converted: Db.Open and Cursor.toArray. The “sync” call wraps a callback with Fiber run/yield that will block in the fiber until callback is returned.
1 Fiber = require 'fibers'
2 mongodb = require 'mongodb'
3 server = new mongodb.Server 'dev', 27017
4
5 Function::sync = (that, args) ->
6 args = if args then Array::slice.call(args) else []
7 fiber = Fiber.current
8 args.push((err, res) ->
9 if err then console.log err
10 fiber.run(err || res)
11 )
12
13 this.apply(that, args)
14
15 result = Fiber.yield()
16 if result instanceof Error then throw result
17 return result
18
19 Cursor = (@cursor) ->
20
21 Cursor::toArray = ->
22 return this.cursor.toArray.sync(this.cursor)
23
24 Db = (@db) ->
25
26 Db::open = ->
27 return this.db.open.sync(this.db)
28
29 Fiber((name) ->
30 db = new Db(new mongodb.Db('test', server, {w:1})).open()
31 sequences = new mongodb.Collection db, 'sequences'
32 s = new Cursor(sequences.find({_id: name})).toArray()
33 console.log s
34 ).run('userid')
35
2 mongodb = require 'mongodb'
3 server = new mongodb.Server 'dev', 27017
4
5 Function::sync = (that, args) ->
6 args = if args then Array::slice.call(args) else []
7 fiber = Fiber.current
8 args.push((err, res) ->
9 if err then console.log err
10 fiber.run(err || res)
11 )
12
13 this.apply(that, args)
14
15 result = Fiber.yield()
16 if result instanceof Error then throw result
17 return result
18
19 Cursor = (@cursor) ->
20
21 Cursor::toArray = ->
22 return this.cursor.toArray.sync(this.cursor)
23
24 Db = (@db) ->
25
26 Db::open = ->
27 return this.db.open.sync(this.db)
28
29 Fiber((name) ->
30 db = new Db(new mongodb.Db('test', server, {w:1})).open()
31 sequences = new mongodb.Collection db, 'sequences'
32 s = new Cursor(sequences.find({_id: name})).toArray()
33 console.log s
34 ).run('userid')
35