2

我对Transcrypt玩得很开心,这是一个很棒的 Python 3 到 Javascript 编译器,可作为python 模块使用。我的大部分代码都是同步的,但我在处理 setTimeout 和 XHR 请求方面没有问题。现在我已经开始使用 PouchDB 进行本地持久性,并试图找到一种处理 Promise 的漂亮方法。目前,我这样做是为了写入 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 的 Promise 的事情(这可能会让我免于疯狂):

  • 是否有更可取的“pythonic”方法来处理这个问题?
  • 可以通过 Transcrypt 使用 ES7 的 async / await 吗?由于 Transcrypt 允许直接从 python 代码中访问 Javascript 函数,我认为这里可能有一些我没有得到的技巧。

谢谢!

4

2 回答 2

3

关于承诺

你处理 promises 的方式对我来说已经够pythonic了。

如果您厌倦了涉及“流利”表示法(调用链)的行延续,可以使用 \. 例如,在 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)

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

关于异步/等待

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

于 2016-10-05T17:28:24.127 回答
1

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

启用 JQuery 使用:

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

定义一个返回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

于 2018-01-12T20:30:55.630 回答