处理JavaScript中被遗忘的承诺

时间:2019-01-28 11:05:49

标签: javascript ecmascript-6 promise

这里有一个例子,希望可以简化问题的理解。

var listen = document.querySelector("#listen"),
  cancel = document.querySelector("#cancel"),
  submit = document.querySelector("#submit");

var promiseResolve = null;

listen.addEventListener("click", startListening);
cancel.addEventListener("click", abort);
submit.addEventListener("click", onSubmitClick);
submit.disabled = true;

function startListening() {
  submit.disabled = false;
  listen.disabled = true;
  new Promise(function(resolve) {
    promiseResolve = resolve;
  }).then(onSubmit);
}

function abort() {
  listen.disabled = false;
  submit.disabled = true;
  promiseResolve = null;
}

function onSubmitClick() {
  if (promiseResolve) promiseResolve();
}

function onSubmit() {
  console.log("Done");
  abort();
}
<button id="listen">Listen</button>
<button id="submit">Submit</button>
<button id="cancel">Cancel</button>

在上面的脚本中,有一个动作(listen)将在submit的帮助下启用另一个动作(Promise)。但是可以使用cancel操作取消该流程,将大多数代码恢复为其原始状态。 cancel操作仅将resolvePromise的引用设置为null,这意味着诺言将永远处于混乱状态,因为它永远不会被解决或拒绝。这些是我的问题:

  • 这种方法正确吗?
  • 这样做会占用大量资源吗?
  • 我还应该保留对拒绝函数的引用,并在cancel操作中调用它吗?

我知道在上面的示例中,仅通过 使用boolean标志检查是否已按下监听按钮 在提交之前,但是就像我说的那样,这只是一个例子,所以我 可以更轻松地解释问题。

1 个答案:

答案 0 :(得分:2)

this答案中所述;

  

大多数使用promise的代码期望它们在某些情况下能够解决或拒绝   指向未来(这就是为什么首先使用诺言的原因)。   如果没有,那么该代码通常永远无法完成其工作。

     

您可能还有其他一些代码可以完成   为那个任务而努力,而诺言却从未被放弃   做它的事情。如果您这样做,则Javascript中没有内部问题   这样,但不是设计诺言的方式,而是   通常,诺言的使用者并不期望诺言如何运作。

无法解决或拒绝承诺不会在Javascript中引起问题,但是无论如何都是不好的做法。您的应用程序如果无法解决,则无法确定诺言发生了什么。而不是让promise陷入困境,而是返回一个错误消息之类的值,并为错误消息提供promise过滤器结果。如果发现错误,请拒绝promise(),以便应用程序确定下一步。

var listen = document.querySelector("#listen"),
  cancel = document.querySelector("#cancel"),
  submit = document.querySelector("#submit");

var promiseResolve = null;

listen.addEventListener("click", startListening);
cancel.addEventListener("click", onCancelClick);
submit.addEventListener("click", onSubmitClick);
submit.disabled = true;

function startListening() {
  submit.disabled = false;
  listen.disabled = true;
  new Promise(function(resolve, reject) {
    promiseResolve = (error) => {
       if (error) { reject(error); } else { resolve(); }
    };
  }).then(onSubmit)
  .catch(error => onError(error));
}

function abort() {
  listen.disabled = false;
  submit.disabled = true;
  promiseResolve = null;
}

function onSubmitClick() {
  if (promiseResolve) promiseResolve();
}

function onCancelClick() {
  if (promiseResolve) promiseResolve("Cancelled!");
}

function onSubmit() {
  console.log("Done");
  abort();
}

function onError(error) {
  console.warn(error);
  abort();
}
<button id="listen">Listen</button>
<button id="submit">Submit</button>
<button id="cancel">Cancel</button>