如果我在 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 Promise 的 node.js 项目的代码覆盖率