es2022
I have been playing around with some new (for us) features in Javascript. It is very convenient to use Object Destructuring when working with CPPoint, CPRect and CPSize.
let { x, y } = CPPointMake(12, 13)
This will assign x and y with 12 and 13.
The variables can have their own names too.
let { x: myX, y: myY } = CPPointMake(12, 13)
This will assign myX and myY with 12 and 13.
This also works with more complex things like a CPRect.
let { origin: { x, y }, size: { width, height } } = CPRectMake(20, 10, 100, 200)
The variables can be named here too.
let { origin: { x: myX, y: myY }, size: { width: myWidth, height: myHeight } } = CPRectMake(20, 10, 100, 200)
The new Arrow Functions also make the code look a little bit cleaner.
let array = [1,2,3,4,5,6,7,8,9]
let result = 0
[array enumerateObjectsUsingBlock:e => result += e]
This will add all numbers in the array and assign it to the variable result. The old code looked like this.
let array = [1,2,3,4,5,6,7,8,9]
let result = 0
[array enumerateObjectsUsingBlock:function(e) { result += e }]
Another nice new feature is "for of". It works the way it should work and not like the old "for in"
let array = [1,2,3,4,5,6,7,8,9]
for (const element of array) {
console.log(element) // prints the element
}
A nice feature of the "for of" is that it can use a custom iterator. This will allow us to use "for of" on CPDictionary and CPSet when we had a custom iterator made. This is not yet pushed to the branch. Something like this:
let dict = @{ @"a": 1, @"b": 2 }
for (const { key, value } of dict) {
console.log(key + @": " + value)
}
This will output:
a: 1
b: 2
We don't have many asynchronous methods in the frameworks but there are some like this in CPURLConnection
:
+ (CPURLConnection)sendAsynchronousRequest:(CPURLRequest)aRequest queue:(CPOperationQueue)aQueue completionHandler:(Function)aHandler;
We could add an async version of these methods without too much work needed. Something like this maybe...
+ (async JSObject /* { response: CPURLResponse, data: CPData, error: CPError } */)sendAsynchronousRequest:(CPURLRequest)aRequest queue:(CPOperationQueue)aQueue
{
return new Promise(function(resolve, reject) {
[[self alloc] _initWithRequest:aRequest queue:aQueue completionHandler:function(aResponse, aData, anError) {
resolve( {response: aResponse, data: aData, error:anError })
}];
});
}
or an even simpler convenience method which defaults to the main queue. (This method is now added in the node branch)
+ (async JSObject /* { response: CPURLResponse, data: CPData, error: CPError } */)sendAsynchronousRequest:(CPURLRequest)aRequest
{
return new Promise(function(resolve, reject) {
[[self alloc] _initWithRequest:aRequest queue:[CPOperationQueue mainQueue] completionHandler:function(aResponse, aData, anError) {
resolve( {response: aResponse, data: aData, error:anError })
}];
});
}
Now we can access this by just doing:
- (async @action)doAction:(id)sender {
const { response, data, error } = await [CPURLConnection sendAsynchronousRequest:[CPURLRequest requestWithURL:@"http://cappuccino.dev"]];
if (error == nil) {
let statusCode = [response statusCode];
//do the stuff...
} else {
// Handle errors
}
}