Hello, I am glad to introduce my work this weekend: continuation for Haxe.
The project is at https://github.com/Atry/haxe-continuation.
Usage
If a function's last parameter is a callback function, it is async function. Use Continuation.cpsFunction to write a async function. InContinuation.cpsFunction, async is a keyword to invoke other async functions.
import com.dongxiguo.continuation.Continuation;
class Sample
{
static var sleepOneSecond = callback(haxe.Timer.delay, _, 1000);
public static function main()
{
Continuation.cpsFunction(function asyncTest():Void
{
trace("Start continuation.");
for (i in 0...10)
{
async(sleepOneSecond);
trace("Run sleepOneSecond " + i + " times.");
}
trace("Continuation is done.");
});
asyncTest(function()
{
trace("Handler without continuation.");
});
}
}haxelib install continuation });
});
});This is great!!It's written with macros?
import js.Node;
import com.dongxiguo.continuation.Continuation;
using Lambda;
/**
* @author 杨博
*/
@:build(com.dongxiguo.continuation.Continuation.cpsByMeta("cps"))
class TestNode
{
/**
* Write <code>content</code> to <code>fd</code>.
*/
@cps static function writeAll(fd:Int, content:String):Null<NodeErr>
{
var totalWritten = 0;
while (totalWritten < content.length)
{
var err, written =
Node.fs.write(
fd, content,
totalWritten, content.length - totalWritten, null).async();
if (err != null)
{
return err;
}
totalWritten += written;
}
}
/**
* Create a directory named "TestNode", and concurrently put 5 files into it.
*/
@cps static function startTest():Void
{
var err = Node.fs.mkdir("TestNode").async();
if (err != null)
{
trace("Node.fs.mkdir failed: " + err);
return;
}
// Lambda.iter() forks threads for each element.
// Fork 5 threads now!
var fileName = ["1.txt", "2.log", "3.txt", "4.ini", "5.conf"].iter().async();
// Note that some asynchronous function return more than one values!
// It's OK in CPS functions, just like Lua.
var err, fd = Node.fs.open("TestNode/" + fileName, "w+").async();
if (err != null)
{
trace("Node.fs.open failed: " + err);
return;
}
// Invoke another CPS function.
var err = writeAll(fd, "Content of " + fileName).async();
if (err != null)
{
trace("Node.fs.write failed: " + err);
return;
}
var err = Node.fs.close(fd).async();
if (err != null)
{
trace("Node.fs.close failed: " + err);
return;
}
}
public static function main()
{
startTest(
function():Void
{
trace("Test is done!");
});
}
}// Read a file from disk and display it. Uses a hand-written callback.
function foo() {
Node.fs.readFile("aFile.txt", function(err, fileContents) {
if(err) {
trace("An error occurred while trying to read the file from disk");
return;
}
trace(fileContents);
});
}// Read a file from disk and display it. Uses CPS magic!
@cps function foo() {
try {
var fileContents = Node.fs.readFile("aFile.txt").async();
trace(fileContents);
} catch(err: Dynamic) {
trace("An error occurred while trying to read the file from disk");
}
}