我有这种情况:
import processAsyncCall from "../helpers/processAsyncCall";
const promiseWrapper = () => new Promise((res, rej) => { /* [1] */ });
const onResolve = () => { /* [2] */ };
dispatch(processAsyncCall(promiseWrapper, onResolve));
promiseWrapper
包含一个承诺,该承诺将在执行特定操作(例如:获取文件、更新内容等(时解决。- 当
promiseWrapper
内部的promise
解析后,将调用此方法。
让我们来看看processAsyncCall
.
export default (
promiseWrapper,
onResolve = null,
) => (dispatch, getState) => {
dispatch(showLoading());
promiseWrapper()
.then(result => {
if (onResolve !== null && typeof onResolve === "function") {
onResolve(dispatch, getState)(result);
}
})
.catch(() => console.log("ERROR_IN_ASYNC"))
.finally(() => dispatch(hideLoading()));
});
};
重要的部分是promiseWrapper().then(result => { /* ... */})
.
我执行函数promiseWrapper
当场创建承诺。
我的问题 :
是否有必要将承诺包装在函数中以确保在处理之前不会解析它?
我遇到了这个问题,如果我直接将Promise作为参数传递,then
回调将不起作用。
dispatch(processAsyncCall(new Promise(/* ... */), /* ... */));
我的理解是,当承诺解析时,将调用then
回调。但是,如果函数解析并且当时没有then
回调,则Promise已完成/完成/死亡。
请记住,上面的示例非常简单,但在某些情况下,Promise是在其他地方创建的,并且它会向下传递,直到它到达processAsyncCall
函数。
我觉得承诺的行为在你的脑海中仍然有点神秘。
你可以想象一个承诺是一个具有4个属性的对象:
- 一个状态,
- 一个值,
- 成功时将调用的回调列表,
- 失败时要调用的回调列表。
state
总是从pending
开始,并且您的 promise 中的代码堆叠起来以便在下一个执行循环中调用,就像您使用setImmediate
调用它一样。
承诺只能解决或拒绝一次,此后将永远保持这种状态。
当承诺被解析/拒绝时,其状态将更改为fulfilled
或rejected
,并按顺序调用相应的回调。
当您调用then
或catch
对 Promise 时,如果 Promise 的状态为pending
,则回调会添加到相应的列表中。如果承诺已经被解析(分别被拒绝(,则回调将在下一个执行循环中调用。
我希望它能帮助你理解这里发生的事情。
我的理解是,当承诺解析时,调用 then 回调。但是,如果函数解析并且当时没有回调,则 Promise 已完成/完成/死亡。
这是不正确的。根据定义,代码无法知道承诺何时解析,并且要求代码在解析之前附加回调会对承诺施加相当大的限制,并使它们的用处大大降低。不,您可以随时附加新的回调,它将被称为:
const p = new Promise(r => {
r('yay');
setTimeout(() => p.then(console.log));
});
p.then(console.log);
您的情况中的区别可能只是processAsyncCall
期望承诺作为参数还是返回承诺的函数。这些是不同的类型,显然必须以不同的方式处理。