I don´t understand the syntax of the then() clause.
1. myFuture(6).then( (erg) => print(erg) )
What´s (erg) => expr syntactically?
I thougt it could be a function, but
then( callHandler2(erg)
doesn´t work, Error:
"Multiple markers at this line
- The argument type 'void' cannot be assigned to the parameter type '(String) ->
dynamic'
- Undefined name 'erg'
- Expected to find ')'"
2. myFuture(5).then( (erg) { callHandler(erg);},
onError: (e) => print (e)
What´s `onError: (e) => expr"` syntactically?
3. Is there a difference between the onError: and the .catchError(e) variants?
1) The Fat Arrow is syntactic sugar for short anonymous functions. The two functions below are the same:
someFuture(arg).then((erg) => print(erg));
// is the same as
someFuture(arg).then((erg) { return print(erg); });
Basically the fat arrow basically automatically returns the evaluation of the next expression.
If your callHandler2 has the correct signature, you can just pass the function name. The signature being that it accept the number of parameters as the future will pass to the then clause, and returns null/void.
For instance the following will work:
void callHandler2(someArg) { ... }
// .. elsewhere in the code
someFuture(arg).then(callHandler);
2) See answer 1). The fat arrow is just syntactic sugar equivalent to:
myFuture(5).then( (erg){ callHandler(erg);}, onError: (e){ print(e); });
3) catchError allows you to chain the error handling after a series of futures. First its important to understand that then calls can be chained, so a then call which returns a Future can be chained to another then call. The catchError will catch errors both synchronous and asynchronous from all Futures in the chain. Passing an onError argument will only deal with an error in the Future its an argument for and for any synchronous code in your then block. Any asynchronous code in your then block will remain uncaught.
Recent tendency in most Dart code is to use catchError and omit the onError argument.
I will attempt to elaborate more on Matt's answer, hopefully to give more insights.
What then() requires is a function (callback), whose signature matches the future's type.
For example, given a Future<String> myFuture and doSomething being any function that accepts a String input, you can call myFuture.then(doSomething). Now, there are several ways to define a function that takes a String in Dart:
Function(String) doSomething1 = (str) => /* do something with str */ // only one command
Function(String) doSomething2 = (str) { /* do something with str */ } // several commands
Function(String) doSomething3 = myFunction;
myFunction(String) { // Dart will auto imply return type here
/* do something with str */ // several commands
}
Any of those 3 function definitions (the right hand side of =) could go inside then(). The first two definitions are called lambda functions, they are created at runtime and cannot be reused unless you manually copy the code. Lambda functions can potentially yield language-like expressions, i.e. (connection) => connection.connect(). The third approach allows the function to be reused. Lambda functions are common in many languages, you can read more about it here: https://medium.com/#chineketobenna/lambda-expressions-vs-anonymous-functions-in-javascript-3aa760c958ae.
The reason why you can't put callHandler2(erg) inside then() is because callHandler2(erg) uses an undefined variable erg. Using the lambda function, you will be able to tell then() that the erg in callHandler2(erg) is the output of the future, so it knows where to get erg value.
Related
I have some code like this:
File("foo.txt").readAsString().catchError((e)=>print(e));
The compiler is complaining
info: The return type 'void' isn't assignable to 'FutureOr<T>', as required by 'Future.catchError'.
I can't seem to give it what it wants and can't find a single clear usage example in any of the docs (just a long issue in git about how many ways there are to mis-use this). If I take the docs at face value, I should be able to return a bool, or a future, neither make the analyzer happy.
How do I provide this FutureOr?
The documentation for Future.catchError could be a lot clearer, but the relevant part is:
onError is called with the error and possibly stack trace, and the returned future is completed with the result of this call in exactly the same way as for then's onError.
Cross-referencing to the documentation for Future.then, the relevant portion is:
The onError callback must return a value or future that can be used to complete the returned future, so it must be something assignable to FutureOr<R>.
Since File.readAsString returns a Future<String>, your catchError callback also must return a Future<String>. Examples of doing that:
File("foo.txt").readAsString().catchError((e) {
print(e);
return Future.value('');
});
File("foo.txt").readAsString().catchError((e) async {
print(e);
return '';
});
Logically, this makes sense; because given:
String value = await File("foo.txt").readAsString().catchError(...);
then if readAsString succeeds, value should be assigned a String. If it fails, since you catch the exception without rethrowing it, value still needs to be assigned a String.
Put another way, your code is equivalent to:
Future<String> readFoo() async {
try {
return await File("foo.txt").readAsString();
} catch (e) {
print(e);
}
// Oops, missing return value.
}
In general, I strongly recommend using async/await with try-catch instead of using .catchError, which would avoid this confusion.
I am looking for an explanation of the 3rd argument in uv.tcp_connect and uv.getaddrinfo. How to get the real function name or fun definition? At tcp_connect I saw this third argument as function(err).
function(err) -error is string
At getaddress has 3rd argument.
function(res,err)
Most of the places callback() or function () is calling.
callback() - how to determine this callback is going to call which API ? I know it's all are callback but in my lua code difficult to find fun definition.
I can only guess what you want to know.
uv.tcp_connect(tcp, host, port, callback) callback is -function(err)
This line tells you that the function uv.tcp_connect has four parameters. tcp, host, port and callback.
callback is a function value with one parameter err.
So you would typically do something like this (assuming err is a str
local myCallback = function (err) print("The error is: " .. err) end
uv.tcp_connect(myTcp, myHost, myPort, myCallback)
Or using an anonymous function:
uv.tcp_connect(myTcp, myHost, myPort, function (err) print("The error is: "..err) end)
At some point the program will call your callback and provide the arguments according to the parameter list.
I have some code like this:
File("foo.txt").readAsString().catchError((e)=>print(e));
The compiler is complaining
info: The return type 'void' isn't assignable to 'FutureOr<T>', as required by 'Future.catchError'.
I can't seem to give it what it wants and can't find a single clear usage example in any of the docs (just a long issue in git about how many ways there are to mis-use this). If I take the docs at face value, I should be able to return a bool, or a future, neither make the analyzer happy.
How do I provide this FutureOr?
The documentation for Future.catchError could be a lot clearer, but the relevant part is:
onError is called with the error and possibly stack trace, and the returned future is completed with the result of this call in exactly the same way as for then's onError.
Cross-referencing to the documentation for Future.then, the relevant portion is:
The onError callback must return a value or future that can be used to complete the returned future, so it must be something assignable to FutureOr<R>.
Since File.readAsString returns a Future<String>, your catchError callback also must return a Future<String>. Examples of doing that:
File("foo.txt").readAsString().catchError((e) {
print(e);
return Future.value('');
});
File("foo.txt").readAsString().catchError((e) async {
print(e);
return '';
});
Logically, this makes sense; because given:
String value = await File("foo.txt").readAsString().catchError(...);
then if readAsString succeeds, value should be assigned a String. If it fails, since you catch the exception without rethrowing it, value still needs to be assigned a String.
Put another way, your code is equivalent to:
Future<String> readFoo() async {
try {
return await File("foo.txt").readAsString();
} catch (e) {
print(e);
}
// Oops, missing return value.
}
In general, I strongly recommend using async/await with try-catch instead of using .catchError, which would avoid this confusion.
The Vala Tutorial has an example about DBus using anonymous methods.
Bus.own_name (BusType.SESSION, "org.example.DemoService", /* name to register */
BusNameOwnerFlags.NONE, /* flags */
on_bus_aquired, /* callback function on registration succeeded */
() => {}, /* callback on name register succeeded */
() => stderr.printf ("Could not acquire name\n")); /* callback on name lost */
I am trying to rewrite this code in Genie, but could not manage to convert the two last lines. The Genie Tutorial only has an example on how to use a closure to define an event handler.
f.my_event += def (t, a)
print "event was detected with value %d", a
How do I use anonymous method definitions in a method call with Genie?
I think there is not way. You must call another process using "def".
Bus.own_name (BusType.SESSION, "org.example.DemoService",
BusNameOwnerFlags.NONE,
on_bus_aquired,
reg,
err);
def reg()
pass
def err()
print "error"
This isn't possible at the moment:
https://bugzilla.gnome.org/show_bug.cgi?id=746704
Currently Genie only support the deprecated lambda syntax for signals
(+=). This patch provides lambda support in most constructs, the only
requirement is that braces and parens need to be indent-balanced on
multiple line constructs.
I try to understand the main concept of callbacks in swift
I have the following code:
typealias ImageHandler = (String,NSError?) -> Void
func PostOnSocialMedia(image:String?){
println(0)
Post({(image)->Void in
println(1)
})
println(2)
}
func Post(handler:ImageHandler){
println(3)
}
my code output is 0,3,2 and my question is why doesn't print the number 1.
It’s not printing 1 because you are passing in a function that is never called.
This:
Post({ (image)->Void in
println(1)
})
declares a temporary function (a “closure expression” – a quick easy way to declare anonymous functions, between the { }) that takes an argument of a (String,NSError?) pair, and returns nothing. Then it passes that function into the Post function.
But the Post function does nothing with it. For a function to run, it needs to be called. If you changed your Post function like so:
func Post(handler:ImageHandler){
println(3)
// call the handler that was passed in...
handler("blah",nil)
}
you’ll see it printing a 1.
Note, the image argument received by PostOnSocialMedia and the image argument variable inside the temporary function are two different variables – scoping rules mean the one declared inside the temp function masks the one in the outer scope. But they are very different (in fact, they’re different types – one is a string, and the other is a 2-tuple of a string and an error).
Try reading this for a short intro on first-order functions and closures in Swift.