【妙用協程】 - 詭異的web框架

在史前的web開發時代(我說的是AngularJS工程師開始變得價值不菲以前的黑暗歲月),web開發的一個痛點在於HTTP是一個無狀態的協議,瀏覽器是一個無狀態的展現表單提交工具。固然如今的web開發世界已經再也不是如此了,瀏覽器已經儼然是一個全功能的客戶端了,B/S和C/S架構的差別已經接近彌合。在那個年代,有一些人就想,讓狀態從服務器傳到瀏覽器,而後再在瀏覽器提交表單的時候傳回來這多麻煩呀。若是可以讓服務器保存表單狀態,代碼寫起來該多麼酷啊,好比下面這個例子(Stackless Python Nagare):web

class Counter(object):

    def __init__(self):
        self.val = 0

    def increase(self):
        self.val += 1

    def decrease(self):
        self.val -= 1

@presentation.render_for(Counter)
def render(counter, h, *args):
    h << h.div('Value: ', counter.val)

    h << h.a('++').action(counter.increase)
    h << '|'
    h << h.a('--').action(counter.decrease)

    return h.root

這段代碼實現的功能是在瀏覽器上顯示一個「0」,而後有++和--兩個連接。點++的話會提交一個HTTP請求給服務器,服務器返回一個新頁面,其上面顯示一個「1」。
背後的思想是把頁面上的內容建模爲一個狀態,在代碼中這個狀態就是那個counter對象。counter對象的值是以協程的方式保存在服務器端的。不單單是counter的值,以及h.a('++').action(counter.increase)這樣綁定的事件與回調函數的映射也被保存了下來了。客戶端的操做經過HTTP發到服務器以後。服務器根據渲染頁面時注入的一些id表示符,找到對應的協程,而後加載協程,再把協程日後執行一步,同時渲染出一個新的HTML頁面,返回給客戶端。相似的想法最出名的框架是smalltalk的seaside。
假設咱們是服務器,當咱們把頁面發給客戶端以後,等待客戶端的返回,而後根據返回執行後面的事情。相似這樣瀏覽器

page1 = initial_render()
send_to_browser(page1)
resp = wait_for_browser_response()
page2 = do_something(resp)
send_to_browser(page2)

中間wait_for_browser_response()就是一個大大的流程阻塞,固然爲何不能用協程去對這個流程阻塞問題進行建模呢。因而乎就有這些詭異的實現了。服務器

相關文章
相關標籤/搜索