如果我们不等待承诺会发生什么

fox*_*xer 4 javascript

我有这个使用给定源播放音频的功能,它工作正常:

function sfxPlay(source) {
  let sfxAudio = new Audio(`${source}`);
  sfxAudio.crossOrigin = "anonymous";
  sfxAudio.play();

  return new Promise((resolve) => {
    sfxAudio.addEventListener("ended", function () {
      sfxAudio.currentTime = 0;
      resolve();
    });
  });
}
Run Code Online (Sandbox Code Playgroud)

我将在这样的异步函数中使用它:

await sfxPlay(source.mp3);
Run Code Online (Sandbox Code Playgroud)

问题是如果我想在没有await? 如果稍后我再次将它与 await 一起使用,这是否会产生任何错误......当我们不等待它时,那个承诺会发生什么?!

编辑: 我的意思是如果我们在函数 A 中有这样的函数:

sfxPlay(source.mp3);
Run Code Online (Sandbox Code Playgroud)

像这样在函数 B 中使用它是否可以接受?

await sfxPlay(source.mp3);
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 10

如果您只是调用该函数并且不对它返回的承诺执行任何操作,则意味着它的结算结果永远不会被处理,这可能很好,也可能成为问题。Promise 可能会发生三件事(无论你是否处理它们):

\n
    \n
  1. 承诺永远不会解决,在这种情况下,您不处理履行或拒绝并不重要,因为它们都不会发生。:-)

    \n
  2. \n
  3. 承诺已经兑现了。那样的话,就完全没有问题了。这就像调用一个函数而不使用它的返回值一样。

    \n
  4. \n
  5. 承诺被拒绝。这就像不处理抛出的异常(根本不在函数本身中,也不在调用它的函数中,让异常继续向上运行到主机环境)。主机至少会向控制台或输出报告“未处理的拒绝”。某些主机可能会在此时终止您的程序。例如,当前(截至本次编辑)版本的 Node.js (v17.1.0) 在发生未处理的拒绝时终止进程(尽管有一种全局方法来处理其他未处理的拒绝)。您可能没有使用 Node.js,但它并不是唯一可能开始以这种方式处理未处理拒绝的主机。

    \n
  6. \n
\n

因此,您可能想使用 Promise,至少捕获错误。如果您的调用是在async函数中,await则将执行该操作\xc2\xa0\xe2\x80\x94,但也会阻止该函数所在函数的承诺的结算asyncawait在非async函数中,或者在async您所在的函数中不想等待结算,就用catch承诺:

\n
sfxPlay(source).catch(()=>{\n    /* ...handle/report the error (or just suppress it, if that\'s appropriate\n       [which it sometimes, though rarely, is])...\n    */\n});\n
Run Code Online (Sandbox Code Playgroud)\n


Toa*_*gma 5

如果你不使用await,你仍然可以使用promise,你只需要手动等待它使用.then(promise只是作为一个普通对象返回):

sfxPlay(source).then(()=>{
    // ...
});
Run Code Online (Sandbox Code Playgroud)

否则,如果你不使用它,默认情况下不会发生任何好或坏的事情——promise 中的代码仍然会运行,但是当你调用resolve.

reject但是,如果您调用,则没有任何东西可以处理拒绝;这糟糕,因为它会在大多数平台上引发错误。因此,reject除非您有匹配项.catch,否则请确保您永远不要使用它(还要注意try/catch语句不适用于这种特定类型的错误)。感谢@TJ Crowder 指出这一点。

您可以混合使用这两种方法而不会出现任何问题。

  • *“...不会发生任何好事或坏事...”* 这取决于您对“坏”的定义。如果承诺被拒绝并且没有任何东西处理拒绝,主机将在控制台/输出中报告未处理的拒绝。当 Node.js 看到未处理的拒绝时,它当前会显示“未处理的 Promise 拒绝已被弃用。将来,未处理的 Promise 拒绝将以非零退出代码终止 Node.js 进程。”* 例如,在某些时候,Node.js 可能会因未处理的拒绝而终止——这绝对是“糟糕的”。:-) (3认同)