是否有必要将承诺包装在函数中?



我有这种情况:

import processAsyncCall from "../helpers/processAsyncCall";
const promiseWrapper = () => new Promise((res, rej) => { /* [1] */ });
const onResolve = () => { /* [2] */ };
dispatch(processAsyncCall(promiseWrapper, onResolve));
  1. promiseWrapper包含一个承诺,该承诺将在执行特定操作(例如:获取文件、更新内容等(时解决。
  2. 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调用它一样。

承诺只能解决或拒绝一次,此后将永远保持这种状态。

当承诺被解析/拒绝时,其状态将更改为fulfilledrejected,并按顺序调用相应的回调。

当您调用thencatch对 Promise 时,如果 Promise 的状态为pending,则回调会添加到相应的列表中。如果承诺已经被解析(分别被拒绝(,则回调将在下一个执行循环中调用。

我希望它能帮助你理解这里发生的事情。

我的理解是,当承诺解析时,调用 then 回调。但是,如果函数解析并且当时没有回调,则 Promise 已完成/完成/死亡。

这是不正确的。根据定义,代码无法知道承诺何时解析,并且要求代码在解析之前附加回调会对承诺施加相当大的限制,并使它们的用处大大降低。不,您可以随时附加新的回调,它将被称为:

const p = new Promise(r => {
r('yay');
setTimeout(() => p.then(console.log));
});
p.then(console.log);

您的情况中的区别可能只是processAsyncCall期望承诺作为参数还是返回承诺的函数。这些是不同的类型,显然必须以不同的方式处理。

最新更新