将承诺与 Transcrypt 结合使用

Using promises with Transcrypt

我和 Transcrypt, a fantastic Python 3 to Javascript compiler available as a python module 玩得很开心。我的大部分代码都是同步的,但我在处理 setTimeout 和 XHR 请求时没有遇到任何问题。现在我已经开始使用 PouchDB 进行本地持久化,并试图找到一种处理承诺的漂亮方法。目前,我这样做是为了写入 pouchdb 实例:

def db_put():

    def put_success(doc):
        print("Put a record in the db. Id: ", doc.id, "rev: ", doc.rev)

    def put_failure(error):
        print('Failed to put a record in the db. Error: ', error)

    strHello = {'_id': "1", 'title': 'hello db'}
    db.put(strHello) \
    .then(put_success) \
    .catch(put_failure)

db = PouchDB('test_db')
document.getElementById("db_put").addEventListener("click", db_put)

这很好用,但我很想知道关于从 python 转换为 Javascript 的承诺的一些事情(这可能会让我免于疯狂):

谢谢!

关于承诺

你处理 promises 的方式在我看来足够 pythonic。

如果您厌倦了涉及 'fluent' 符号(调用链)的行延续,可以使用 \ 的替代方法。例如使用此替代方案在Transcrypt自带的d3js_demo中,在下面的片段中:

self.svg = d3.select('body'
).append('svg'
).attr('width', self.width
).attr('height', self.height
).on('mousemove', self.mousemove
).on('mousedown', self.mousedown)

由于许多 .then 也可以链接,因此可以这样写:

db.put(strHello
).then(put_success
).then(put_success_2
).then(put_success_3
... etc.
).catch(put_failure)

经过一些习惯后,这将立即明确涉及调用链。但这只是格式问题。

关于async/await

它们还不受支持,但计划是在 JS 正式拥有它们后不久(我希望是 JS7)。现在您可以使用 __pragma__ ('js', '{}', '''<any javascript code>''') 作为解决方法。

Async/await 现在支持了一段时间。您可以使用它来处理 Promises。例如:

启用JQuery 用法:

__pragma__ ('alias', 'S', '$')

定义一个 returns 一个 Promise 的函数,在本例中是一个 Ajax 调用:

def read(url: str) -> 'Promise':
    deferred = S.Deferred()
    S.ajax({'type': "POST", 'url': url, 'data': { },
        'success': lambda d: deferred.resolve(d),
        'error': lambda e: deferred.reject(e)
    })
    return deferred.promise()

异步代码当作同步使用:

async def readALot():
    try:
        result1 = await read("url_1")
        result2 = await read("url_2")
    except Exception:
        console.warn("Reading a lot failed")

浏览器python使用愉快