如果我在 Kriskowal 的 q 中多次拒绝/解决会发生啥?

Posted

技术标签:

【中文标题】如果我在 Kriskowal 的 q 中多次拒绝/解决会发生啥?【英文标题】:What happens if i reject / resolve multiple times in Kriskowal's q?如果我在 Kriskowal 的 q 中多次拒绝/解决会发生什么? 【发布时间】:2013-08-15 13:46:12 【问题描述】:

我正在研究 promise 模式并使用 kriskowal 的 q for node.js,

有这个sn-p:

var deferred = Q.defer();
try 
    messageData = JSON.parse(message);
 catch (e) 
    global.logger.warn('Error parsing JSON message.');
    deferred.reject(e);

...
if (some_reason)
    deferred.resolve(something);
...
return deferred.promise;

如果解析器都失败并且 some_reason 为真怎么办?

是否会从rejected到resolve继续执行,并且两个promise的方法在不同的时间被调用,从而产生一个bug?

我应该避免多次调用拒绝/解决吗?

【问题讨论】:

【参考方案1】:

原帖here

see github gist: reuse_promise.js

/*
reuse a promise for multiple resolve()s since promises only resolve once and then never again
*/

import React,  useEffect, useState  from 'react'

export default () => 
    
    const [somePromise, setSomePromise] = useState(promiseCreator())
        
    useEffect(() => 
        
        somePromise.then(data => 
            
            // do things here
            
            setSomePromise(promiseCreator())
        )
        
    , [somePromise])


const promiseCreator = () => 
    return new Promise((resolve, reject) => 
        // do things
        resolve(/*data*/)
    )

【讨论】:

【参考方案2】:

由于promises can only resolve once(满足拒绝),第一个解决方案获胜,任何进一步的调用都将被忽略。来自the docs:

在所有解决承诺的情况下(即履行或拒绝),解决方案是永久性的,无法重置。如果 promise 已经解决,尝试调用 resolve、reject 或 notify 将是无操作的。

我应该避免多次调用拒绝/解决吗?

您甚至可以设计您的应用程序,让两种方法相互“竞争”以解决延迟问题,但通常应避免这样做以减少读者的困惑。

【讨论】:

我不知道比赛,我已经使用 jQuery deferreds 来解决这个问题。例如一旦用户单击或时间用完,就转到下一个屏幕。 “以先到者为准”。我觉得奇怪的是,像 Kew.js 这样的库在尝试解析两次时实际上会抛出错误。 :( @bfred.it:是的,你可以做到这一点。但最好明确地执行Q.race(getNextUserClick(), Q.timeout(…)).then(nextScreen) 而不是having a single deferred 并多次手动解决。 Race 很有趣,但不幸的是,kew.js 实际上并没有。 jsbin.com/gemepay/3/edit?js,console ;通过这个例子,既然第一个承诺解析为值 1,那么为什么其他调用也解析为 1 呢?据我所知,一旦解决,其他 '.then()' 调用默认为第一次计算的值。 @motan 不清楚您所说的“第一个承诺”是什么意思。您的代码中只有一个(相关的)promise,p,并且这个单一的 promise 确实有一个单一的结果值。在一个 Promise 上安装多少个 then 回调(零个、一个或多个)并不重要,它们不会影响 Promise 的解析。

以上是关于如果我在 Kriskowal 的 q 中多次拒绝/解决会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 q 进行回调链?

使用 Q Promise 的 node.js 项目的代码覆盖率

Tomcat 7.0.42 上的 403 访问被拒绝

拒绝执行脚本,启用严格的 MIME 类型检查?

是否有一种纯粹的基于 Promise 的映射/连接集合的方法?

如果我在 iTunes Connect 中点击“拒绝二进制文件”以提交更新的二进制文件,我会失去排队的位置吗?