Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Deus Rex
Mar 5, 2005

Suspicious Dish posted:

JavaScript code:
function parseGoogle() {
    var promise = new Promise();

    var task = fetchPage("http://google.com");
    task.addCallback(parseGoogleInWebWorker);
    task.addCallback(promise.callback);
}

this isn't compliant with any of the promises specs, what implementation uses addCallback and not then?

Every implementation I've seen you'd write like this:

JavaScript code:
// @return {Promise} resolved or rejected with the result of parseGoogleInWebWorker
// if the impl is Promises A+ compliant, an exception thrown in parseGoogleInWebWorker
// rejects the promise
function parseGoogle() {
  // fetchPage returns a Promise 
  return fetchPage('http://google.com').then(parseGoogleInWebWorker); 
}

Deus Rex fucked around with this message at 05:14 on Apr 18, 2013

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I was basing it off of Twisted's Deferreds (implemented in Dojo and Caja and a bunch of other things) because I'm a moron.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

The Insect Court posted:

Obviously, since Coffeescript is ultimately just Javascript, it can't really change the semantics. But given how much of a pain in the rear end a lot of Javascript syntax is to work with, syntactic sugar is a big positive. There are plenty of examples of Coffeescript one-liners involving syntactical sugar like list comprehensions that would require vastly more code in plain Javascript. The lack of a module system is a glaring oversight when it comes to programming with Javascript in the large, but that's not something Coffeescript can fix by itself, and the available solutions like requirejs are still compatible with Coffeescript.

I write JavaScript for a living and I don't think it's that much of a pain in the rear end. List comprehensions are nice and all, but I don't think I've ever encountered a situation in a real project (as opposed to a toy example) where just using various array utility functions isn't sufficiently clear.

DreadCthulhu
Sep 17, 2008

What the fuck is up, Denny's?!
Any advice for how to best handle n outgoing ajax requests all trying to fill a single object/array? In my case they're Parse queries, but he principle should be the same. I like promises, but it'd be great if I could have the same principle work for more than 1 request at a time. At this point I just count how many callbacks completed and kick off the use of the data once they're all done.

thathonkey
Jul 17, 2012

DreadCthulhu posted:

Any advice for how to best handle n outgoing ajax requests all trying to fill a single object/array? In my case they're Parse queries, but he principle should be the same. I like promises, but it'd be great if I could have the same principle work for more than 1 request at a time. At this point I just count how many callbacks completed and kick off the use of the data once they're all done.

Do you mean you're trying to run a bunch of AJAX requests in parallel and have a single callback for when they are all completed? You can do this via jQuery promises, using $.when(). See the bottom example here:

http://api.jquery.com/jQuery.when/

You can rewrite it to be more clear though:

code:
req1 = $.ajax();
req2 = $.ajax();
req3 = $.ajax();

$.when(req1, req2, req3).then(function () { // do something on success });

DreadCthulhu
Sep 17, 2008

What the fuck is up, Denny's?!
Excellent, that worked well.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS
I actually had a question about promises that I was hoping someone would help me with. I understand that using $.when().then() let's you fire a callback in then() once the actions in .when() are completed, but how do you go about returning the data from the actions in .when()? What I mean by that is say I have a function that does my requests and one that handles synchronizing the requests using promises.

For example (CoffeeScript):
code:
_submitQuery = ->
  $.when(AJAX.query(false), AJAX.query(true)).then((queryResults, nationalResults) ->
    response =
      'query': AJAX.normalize queryResults[0]
      'national': AJAX.normalize nationalResults[0]
    return
    )
I have a set of event handlers in which I'd like to work with the response data. However, returning from _submitQuery just gives me the promise object in an unresolved state. How do I make sure that 1) the promise is resolved, and 2) I can get the data that's being returned from the request?

thathonkey
Jul 17, 2012
I'm not sure I understand... when your first callback (success) provided to .then() is called, then the promise is resolved at that point and the data returned from the request is available as the arguments to that callback if I'm not mistaken. Is that not the case with your example? I am admittedly a little rusty on promises API.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS
I'm pretty sure (although not 100%) that you're referring to the difference between then() and done(). My understanding is that done() resolves the promise if any of the arguments passed succeed, but then() only resolves if both succeed. What I want is to return the value from both successes (modified in the way I want) to the calling function. Doesn't seem like it should be difficult, but all I get back is an unresolved promise.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
JQuery can't magically interrupt your javascript to wait for something to happen - it's not something that the language supports at all. You need to use a callback if you want part of your code to execute only after some asynchronous event has happened.

Promises are all about cleaning up callback soup and making them easier to manage, but it can't get rid of them entirely since the language doesn't support it.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Jabor posted:

Promises are all about cleaning up callback soup and making them easier to manage, but it can't get rid of them entirely since the language doesn't support it.

And thus we have trampolines!

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

Jabor posted:

Promises are all about cleaning up callback soup and making them easier to manage, but it can't get rid of them entirely since the language doesn't support it.

Am I wrong that this seems kind of dumb when you're dealing with a large and fairly complex bit of JavaScript? I mean, if I have a bunch of event handlers, I want to have common AJAX code so I can get, merge, and return data to the event handlers. But the way the promise system is set up, it seems like i have to handle the data within the AJAX call or a callback rather than be able to return it to the calling event handler.

Maybe I'm not quite understanding the best way to go about it, but if I have a doAjax() function and a mergeRequests() function that are both called from init() (for example) it seems like I can't get the retrieved, merged value back in init().

Instead it looks like I have to have the contents of mergeRequests() which deal with resolving promises within init() or eventHandler1() or eventHandler2(), etc.

It just seems like it's not very DRY and that kind of irks me. It makes me wish JavaScript could do on-demand blocking.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
The usual way to do that is to have your init function set up its own callback on the promise that it gets back, and then just stop. So instead of looking like this:

JavaScript code:
function init() {
  doAsyncStuff();
  doMoreStuffAfterwards();
}
it looks like this:

JavaScript code:
function init() {
  doAsyncStuff().then(function() {
    doMoreStuffAfterwards();
  });
}

thathonkey
Jul 17, 2012

Blinkz0rz posted:

Maybe I'm not quite understanding the best way to go about it, but if I have a doAjax() function and a mergeRequests() function that are both called from init() (for example) it seems like I can't get the retrieved, merged value back in init().

That's correct. You have to approach an async language like JavaScript differently than you would a procedural one. That's just the way it is.

If you can't initialize your class or app or whatever until all of your data is loaded and merged, you could write it more like this:

code:
function MyClass() {
  var init = function () {
    // your data is loaded, merge it and initialize the app
  };

  // this will fire as soon as the class is instantiated
  try {
     $.when(loadData()).then(init);
  } catch (err) { throw err; }
}

var myApp = new myClass();
If you ever get into server-side/NodeJS development, a lot of functions where it makes sense to have blocking versions (like file system API) comes with async and sync versions.

thathonkey fucked around with this message at 14:37 on Apr 21, 2013

The Insect Court
Nov 22, 2012

by FactsAreUseless
So, apropos about my bitching about vanilla JS last page, can anyone recommend a stable JS-ish language that compiles to ECMAScript 3 JS? I'm running into a lot of pain in the rear end with weird behavior and corner cases regarding how CoffeeScript deals with this and with global and local variable declaration. How's Google Traceur?

Related to that, can I also mention how I absolutely despise how Javascript(and Coffeescript to a degree) is designed to make certain things "easy" for beginners in ways that cripple the language for non-beginners? Letting certain operations fail silently may keep new programmers from being hit with stack traces they don't understand but it means errors propagate silently through the code in ways that make it a pain to debug.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I'm still not sure what's actually wrong with Javascript. There might be warty bits in the language, but no-one forces you to explore every nook and cranny when writing a program.

If you really want you could use something like Closure Compiler I guess.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
It wasn't "designed to be easy" or anything like that. Weak typing was fashionable at the time.

thathonkey
Jul 17, 2012
I would suggest just learning how to write quality JS... it isn't that hard. Seems like you'll spend just as long learning the idiosyncrasies of the various languages that target JS.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

The Insect Court posted:

Related to that, can I also mention how I absolutely despise how Javascript(and Coffeescript to a degree) is designed to make certain things "easy" for beginners in ways that cripple the language for non-beginners? Letting certain operations fail silently may keep new programmers from being hit with stack traces they don't understand but it means errors propagate silently through the code in ways that make it a pain to debug.

Are you using "use strict"; ? Always use strict mode.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Jabor posted:

I'm still not sure what's actually wrong with Javascript.

The most common answer:

Crockford posted:

JavaScript is most despised because it isn't SOME OTHER LANGUAGE. If you are good in SOME OTHER LANGUAGE and you have to program in an environment that only supports JavaScript, then you are forced to use JavaScript, and that is annoying. Most people in that situation don't even bother to learn JavaScript first, and then they are surprised when JavaScript turns out to have significant differences from the SOME OTHER LANGUAGE they would rather be using, and that those differences matter.

The Insect Court
Nov 22, 2012

by FactsAreUseless

Suspicious Dish posted:

It wasn't "designed to be easy" or anything like that. Weak typing was fashionable at the time.

Weak typing is a design decision with its own trade-offs, forcing indefinite arity and not throwing errors on lookups of non-existent object properties is just nuts. And then of course there's the way Javascript does prototypal inheritance but in a weird half-assed way which means most JS programmers end up using a bolted on library that gives it an imitation class-based inheritance system.

thathonkey
Jul 17, 2012

The Insect Court posted:

Weak typing is a design decision with its own trade-offs, forcing indefinite arity and not throwing errors on lookups of non-existent object properties is just nuts. And then of course there's the way Javascript does prototypal inheritance but in a weird half-assed way which means most JS programmers end up using a bolted on library that gives it an imitation class-based inheritance system.

Use strict mode (as is recommended by basically every serious JS programmer today) and the first part of your argument goes away. Also in most implementations even without strict mode, the language will throw a fatal error on the lookup of a non-existence object properties. What does that have to do with weak typing? Furthermore, it is because most programmers don't understand prototypal inheritance that they try to cram functionality from other (class-based) languages into JS via various libraries. Basically echoes the Crockford quote posted above.

This is just another "why doesn't JavaScript behave just like X language" argument and worse is that you seem to be conflating various concepts here...

thathonkey fucked around with this message at 02:06 on Apr 28, 2013

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
To be fair, the prototypal inheritance in JS is kind of wonkey - here's my favourite patch for it though:

JavaScript code:
function object(x) {
  var f = function(){};
  f.prototype = x;
  return new f();
}
And now you have actual prototypal inheritance instead of some weird compromise that kinda sorta looks like it could be either.

The Insect Court
Nov 22, 2012

by FactsAreUseless

thathonkey posted:

Use strict mode (as is recommended by basically every serious JS programmer today) and the first part of your argument goes away. Also in most implementations even without strict mode, the language will throw a fatal error on the lookup of a non-existence object properties. What does that have to do with weak typing? Furthermore, it is because most programmers don't understand prototypal inheritance that they try to cram functionality from other (class-based) languages into JS via various libraries. Basically echoes the Crockford quote posted above.

This is just another "why doesn't JavaScript behave just like X language" argument and worse is that you seem to be conflating various concepts here...

Weak typing is a language design decision that has both downsides(harder to catch certain errors at compile time) and upsides(duck typing). I'm not aware of any languages where the lookup of a property on an object(or hashmap, dictionary, etc.) will fail silently and return something like 'undefined' due to a typo. If I'm trying to retrieve myObject.username, myObject.usernmae should through an error.

I understand prototypal inheritance, but Javascript doesn't. The right way to do prototypes(check out Io if you want an example) is to have a prototype chain that goes from an object up to the object it was cloned from and so on. But Javascript introduces the .prototype object and the use of new as a constructor which makes its inheritance model into a weird prototypal-classical hybrid.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Jabor posted:

To be fair, the prototypal inheritance in JS is kind of wonkey - here's my favourite patch for it though:

JavaScript code:
function object(x) {
  var f = function(){};
  f.prototype = x;
  return new f();
}
And now you have actual prototypal inheritance instead of some weird compromise that kinda sorta looks like it could be either.

aka "Object.create"

thathonkey
Jul 17, 2012

The Insect Court posted:

Weak typing is a language design decision that has both downsides(harder to catch certain errors at compile time) and upsides(duck typing). I'm not aware of any languages where the lookup of a property on an object(or hashmap, dictionary, etc.) will fail silently and return something like 'undefined' due to a typo. If I'm trying to retrieve myObject.username, myObject.usernmae should through an error.

I understand prototypal inheritance, but Javascript doesn't. The right way to do prototypes(check out Io if you want an example) is to have a prototype chain that goes from an object up to the object it was cloned from and so on. But Javascript introduces the .prototype object and the use of new as a constructor which makes its inheritance model into a weird prototypal-classical hybrid.

Oops you're right about object property lookup. I don't know what I was thinking of... I could've sworn I've gotten fatal errors around accessing invalid/undefined properties but maybe I am mistaken. Sorry about that.

I see what you mean about prototypal inheritance but many browsers do support Object.create() and those that don't hardly require a library to fix it:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create#Cross-browser_compatibility

edit: better linking to MDN

thathonkey fucked around with this message at 14:19 on Apr 28, 2013

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

thathonkey posted:

Oops you're right about object property lookup. I don't know what I was thinking of... I could've sworn I've gotten fatal errors around accessing invalid/undefined properties but maybe I am mistaken. Sorry about that.

You're probably thinking about something like someObject.prop.otherProp.aFunction(), where one of the properties in the chain is missing.

thathonkey
Jul 17, 2012

Wheany posted:

You're probably thinking about something like someObject.prop.otherProp.aFunction(), where one of the properties in the chain is missing.

Ah yup, that's correct. I actually went so far as to write a helper/utility for safely checking for the existence of deep properties. It really comes in handy when working with complex (read: poorly structured) JSON feeds and whatnot. If anyone is interested let me know and I can throw it up as a gist or something. The api isn't the most intuitive thing in the world as it is written for performance but it would be used like this (using your example from above) when trying to decide of 'aFunction' is safe to call without checking each depth explicitly:

code:
isDef(someObject, ['prop', 'otherProp', 'aFunction'])

Hughlander
May 11, 2005

Wheany posted:

You're probably thinking about something like someObject.prop.otherProp.aFunction(), where one of the properties in the chain is missing.

Which leads to writing coffeescript like someObject?.prop?.otherProp?.afunction?() or other horrible code.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Heyo, I'm writing a WebSQL / IndexedDB Abstraction and I've hit a little roadblock in understanding with WebSQL. The objects that come out of a query are read only so I can't do anything with them, what's the correct way to make them mutable? Or should I just read variables out to a copy?

edit: Well,I just did object copying cause it's easy (yet for some reason I didn't think fo that til I did this post). Still, can you remove readonly status from an object's properties?

Maluco Marinero fucked around with this message at 13:52 on May 5, 2013

darthbob88
Oct 13, 2011

YOSPOS
I need to scrape and upload a large hunk of HTML from a page and send it to a server for logging purposes. I can scrape it just fine, and I've managed to shrink it to about 11K of text, but I don't think I can just tack it onto a querystring like "?action=newreply&threadid=2718078&html=11K_of_junk". Is there a good way to transmit 11K of data from within JS? I can use jQuery, so AJAX is an option, but I'm open to other possibilities.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

darthbob88 posted:

I need to scrape and upload a large hunk of HTML from a page and send it to a server for logging purposes. I can scrape it just fine, and I've managed to shrink it to about 11K of text, but I don't think I can just tack it onto a querystring like "?action=newreply&threadid=2718078&html=11K_of_junk". Is there a good way to transmit 11K of data from within JS? I can use jQuery, so AJAX is an option, but I'm open to other possibilities.

code:
jQuery.post();
And you are done.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
OK, this is a really dumb and simple question that I should be able to find the answer to on Google. Unfortunately it's one of those things where when you google it all you can find are discussions of a different problem relating to the same keywords.

I have a JSON file (a JSON schema) I'm writing by hand. The following line is in there (sorry for tables):

code:
"pattern": "^([012] ?/ ?2)|([0-3] ?/ ? 3)|([0-4] ?/ ?4)|([0-6] ?/ ?6)|([0-8] ?/ ?8)|(([0-9]|1[012]) ?/ ?12)$"
I want to write this on two lines so it doesn't scroll off to the right in my editor. How do I do this in JSON? (I could use JSON schema's "oneOf" keyword to split this into two separate regular expressions, but it seems like a hack around the language, or whatever JSON is if "language" isn't the right word.) I Google but I can only find stuff about creating strings that have actual line breaks in them, which isn't what I want, I just want to write a string, that doesn't have a line break in it, on two lines.

o.m. 94
Nov 23, 2009

Just fiddling around with AJAX requests. The problem I have (see output) is that load_text_file() completes before the AJAX request does, so the response variable is always undefined. Only afterwards is reqListener() called and the contents of the file is output.

It's confusing because I would expect the oReq XMLHttpRequest object to die when load_text_file() falls off the stack since it's locally scoped. But some point after the death of load_text_file(), reqListener is called. At that point, I see no way to get at the response variable any way.

This could be solved by making a global variable that gets the contents of the response text when reqListener is called, but it seems ugly to have to have that assignment inside the function, as if it's dependent on some external variable. I feel like a closure or something cool could be used just to give me my goddamn response text.

code:
function load_text_file()
{
	function reqListener() {
		if (this.readyState == 4 && this.status == 200) {
  				response = this.responseText;
  				console.log(response);
  		}
	}

 	var response;
	var oReq = new XMLHttpRequest();
	oReq.onreadystatechange = reqListener;
	oReq.open("get", "file.txt", true);
	oReq.send();
	return response;
}

console.log(load_text_file());
Output
code:
test.js:18 	undefined
test.js:6	the contents of my text file!!

o.m. 94
Nov 23, 2009

Turns out I need a callback passed through to be called upon completion of the request. Still, I'm quite interested to know how the XMLHttpRequest object persists outside of the function once it's off the stack.

code:
function load_file(file, callback)
{
	function reqListener() 
	{
		if (this.readyState == 4 && this.status == 200) 
  			callback(this.responseText);
  	}
	
	var oReq = new XMLHttpRequest();
	oReq.onreadystatechange = reqListener;
	oReq.open("GET", file, true);
	oReq.send();
}

var log = function(r) { console.log(r); };
load_file("file.txt", log);

OddObserver
Apr 3, 2009
http://www.w3.org/TR/XMLHttpRequest/#garbage-collection

(Note: it's never on the stack, the local is just a reference to a heap object).

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

oiseaux morts 1994 posted:

Turns out I need a callback passed through to be called upon completion of the request.

Congratulations, you just took your first step into Javascript. Callbacks as far as the eye can see.

o.m. 94
Nov 23, 2009

Wheany posted:

Congratulations, you just took your first step into Javascript. Callbacks as far as the eye can see.

Babby's First Closure

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.

Wheany posted:

Congratulations, you just took your first step into Javascript. Callbacks as far as the eye can see.

and promises.. They're fun too.

Adbot
ADBOT LOVES YOU

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Maluco Marinero posted:

and promises.. They're fun too.

So, I looked up promises, and followed some links, which lead me to this video:

Douglas Crockford: Monads and Gonads (YUIConf Evening Keynote)
https://www.youtube.com/watch?v=dkZFtimgAcM

And I just want to warn you that as a new convert I just might become insufferable.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply