Sometimes you'll have objects that manage state along with event handling. This happens frequently in MVC apps. Let's start with a messy example:
var Launcher = function(rocket) {
this.rocket = rocket
}
Launcher.prototype.isReady = function() {
| import os | |
| import httplib | |
| import tornado.web | |
| class ErrorHandler(tornado.web.RequestHandler): | |
| """Generates an error response with status_code for all requests.""" | |
| def __init__(self, application, request, status_code): | |
| tornado.web.RequestHandler.__init__(self, application, request) | |
| self.set_status(status_code) | |
| class AdminFileHandler(BaseHandler): | |
| @authenticated | |
| def get(self, file_name): | |
| _file_dir = os.path.abspath("")+"/my/path/downloads" | |
| _file_path = "%s/%s" % (_file_dir, file_name) | |
| if not file_name or not os.path.exists(_file_path): | |
| raise HTTPError(404) | |
| self.set_header('Content-Type', 'application/force-download') | |
| self.set_header('Content-Disposition', 'attachment; filename=%s' % file_name) |
Asynchronous programming can be tricky for beginners, therefore I think it's useful to iron some basic concepts to avoid common pitfalls.
For an explanation about generic asynchronous programming, I recommend you one of the [many][2] [resources][3] [online][4].
I will focus on solely on asynchronous programming in [Tornado][1]. From Tornado's homepage:
A lot of times you are developing a web application on your own laptop or home computer and would like to demo it to the public. Most of those times you are behind a router/firewall and you don't have a public IP address. Instead of configuring routers (often not possible), this solution gives you a public URL that's reverse tunnelled via ssh to your laptop.
Because of the relaxation of the sshd setup, it's best used on a dedicated virtual machine just for this (an Amazon micro instance for example).
| def log_exception(view_func): | |
| """ log exception decorator for a view, | |
| """ | |
| def _decorator(self, *args, **kwargs): | |
| try: | |
| response = view_func(self, *args, **kwargs) | |
| except: | |
| if self.settings['debug']: | |
| raise | |
| tb = traceback.format_exc() |
| import hashlib, hmac, mimetypes, os, time | |
| from base64 import b64encode, b64decode | |
| from calendar import timegm | |
| from datetime import datetime | |
| from email.utils import formatdate | |
| from urllib import quote | |
| from tornado.gen import coroutine, Return | |
| from tornado.httpclient import AsyncHTTPClient, HTTPError |
| <html> | |
| <head> | |
| <title>WebSocket demo</title> | |
| </head> | |
| <body> | |
| <div> | |
| <form> | |
| <label for="numberfield">Number</label> | |
| <input type="text" id="numberfield" placeholder="12"/><br /> |
| // SHARE COUNT | |
| $.getJSON("https://graph.facebook.com/fql?q=SELECT like_count FROM link_stat WHERE url=" + encodeURIComponent('"' + Screenshot.Meta.full_url + '"') + " &callback=?", function(t) { | |
| t.data[0] && $("#share-button-fb .shot-social-count").html(shorterTotal(t.data[0].like_count)) | |
| }) | |
| $.getJSON("http://cdn.api.twitter.com/1/urls/count.json?url=" + encodeURIComponent(Screenshot.Meta.full_url) + "&callback=?", function(t) { | |
| t.count && $("#share-button-twitter .shot-social-count").html(shorterTotal(t.count)) | |
| }) |