【问题标题】:Effective Python equivalent of this simple promise-chaining JavaScript class这个简单的 Promise-chaining JavaScript 类的有效 Python 等价物
【发布时间】:2020-02-26 05:06:40
【问题描述】:

这是 JavaScript 代码:

class TaskQueue {
  constructor() {
    this._chain = Promise.resolve();
  }
  postTask(task) {
    const result = this._chain.then(task);
    this._chain = result.catch(() => {});
    return result;
  }
}

我很确定这只是接受一个任务(函数),从中获取 Promise,忽略错误,并将其添加到类“链”中。不过,我不太确定为什么。 Here's the file 有问题,here 是您可以找到它正在使用的地方。在使用上,对我来说似乎真的不需要排队系统。

我不知道用 Python 做什么。我知道没有与这种风格的 Python 代码“完全”等价的东西,但我想有效地复制它,或者即使通过不同的方法,至少也能达到与 JS 相同的结果。

【问题讨论】:

    标签: python-3.x promise queue python-asyncio


    【解决方案1】:

    then 创建一个新的承诺,在旧承诺解决后运行。在 Python 中,您可以创建一个协程等待前一个协程的任务。比如:

    class TaskQueue:
        def __init__(self):
            fut = asyncio.get_event_loop().create_future()
            fut.set_result(None)
            self._task = fut
    
        def post_task(self, awaitable):
            async def run_awaitable(prev):
                try:
                    await prev
                    await awaitable
                except:
                    pass  # consider at least logging here
            self._task = asyncio.create_task(run_awaitable(self._task))
    

    【讨论】:

    • 你不应该将prev的输出分配给result吗?
    • @MattM。现在已修复,result 变量仍保留在以前版本的代码中。
    【解决方案2】:

    这是一个 Javacript Promise 副本的示例:

    class Promise:
        def __init__(self, callback):
            self.resolved = ''
            self.rejected = ''
            if callable(callback):
                callback(self.resolve, self.reject)
    
        def resolve(self, value):
            self.resolved = value
    
        def reject(self, value):
            self.rejected = value
    
        def then(self, callback):
            if not self.rejected:
                self.resolved = callback(self.resolved)
            return self
    
        def catch(self, callback):
            if self.rejected:
                self.rejected = callback(self.rejected)
            return self
    
        def all(self, promises):
            resolvedArray = []
            rejectedArray = []
            for promise in promises:
                promise(self.resolve, self.reject)
                if self.resolved:
                    resolvedArray += self.resolved
                if self.rejected:
                    rejectedArray += self.rejected
                    break
            self.resolved = resolvedArray
            self.rejected = rejectedArray
            return self
    
    
    def myPromise1(resolve, reject):
        resolve(['Ana'])
    
    
    def myPromise2(resolve, reject):
        resolve(['Bia'])
    
    
    def myPromise3(resolve, reject):
        resolve(['Carlos'])
    
    
    def myPromise4(resolve, reject):
        resolve(['Daniel'])
    
    
    def allResolve(values):
        print('without error: ', values)
    
    
    def allReject(values):
        print('with error: ', values)
    
    
    p = Promise([])
    p.all([myPromise1, myPromise2]).then(allResolve).catch(allReject)
    

    另一个例子:

    def myPromise(resolve, reject):
        resolve(['Ana', 'Bia', 'Carlos', 'Daniel'])
    
    
    def firstResolve(value):
        return value[0]
    
    
    def secondResolve(value):
        print(value)
    
    
    def firstReject(value):
        print('error:', value)
    
    
    p = Promise(myPromise)
    p.then(firstResolve).then(secondResolve).catch(firstReject)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-13
      • 2014-04-26
      • 2016-12-24
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      相关资源
      最近更新 更多