我可以在nodejs(ES7)中解雇并忘记一个承诺吗?

Posted

技术标签:

【中文标题】我可以在nodejs(ES7)中解雇并忘记一个承诺吗?【英文标题】:Can I fire and forget a promise in nodejs (ES7)? 【发布时间】:2015-11-29 19:24:58 【问题描述】:

我想用 babel 运行这段代码:

redisClientAsync.delAsync('key');
return await someOtherAsyncFunction();

在没有 await 第一行的异步函数中。这样可以吗?

我还能如何运行我不关心的东西?

我可以在没有回调的情况下触发非承诺函数 del('key',null) 吗?

【问题讨论】:

运行它的进程在异步调用完成之前不退出就可以了。 你在使用 Babel 吗?这是 ES7 的特性。 @MinusFour 是的,我正在使用 babel @mostruash 不可能知道吧?我将创建一个竞争条件 【参考方案1】:

是的,你可以这样做,它会并行运行两个异步函数。您刚刚创建了一个承诺并将其丢弃。

但是,这意味着当 Promise 被拒绝时,您不会注意到。您只需get an unhandledRejection eventually,如果不处理,您的进程就会崩溃。

这样好吗?如何运行我不关心的东西?

可能不太好。如果你真的不在乎,你一开始就没有运行它。所以你应该清楚明确你关心什么(什么不关心):

您要等待吗? (针对副作用) 您需要结果吗? 是否要捕获异常?

如果你只想等待而不关心结果值,你可以很容易地把结果扔掉:

void (await someAsyncFunction()); // or omit the void keyword,
                                  // doesn't make a difference in an expression statement

如果您不关心异常,可以使用忽略它们

… someAsyncFunction().catch(function ignore() ) …

你可以把它扔掉,等待它,用它做任何事情。

如果你想要结果,你必须等待它。如果您关心异常,但又不想等待,您可能希望与以下函数并行执行它:

var [_, res] = await Promise.all([
    someAsyncFunction(), // result is ignored, exceptions aren't
    someOtherAsyncFunction()
]);
return res;

【讨论】:

谢谢你说的很全面。如果我不想要结果,错误并且我不想等待异步函数中最好的。运行 promise 还是运行带有 null(或函数不做任何事情)回调的普通函数(非承诺)? 在这种情况下,您可能也可以省略承诺。我仍然会传递一个显式不执行任何操作的回调,以表明它是异步的,但您会忽略错误。 如果解决了,下一个 .then 会被调用吗?我不想要它。 @mylord 我不明白你的意思。 onfulfill 回调总是在 promise 完成时被调用。 @mylord 如果您在第 7 行返回,第 10 行将仅在 promisifiedFunction() 承诺履行时执行。如果你不这样做,它将在承诺链(现在与promisifiedFunction() 完全无关)完成时执行。如果您对此仍有疑问,您可能应该ask a new question 提供完整的示例和说明。【参考方案2】:

在没有等待第一行的异步函数中。这样可以吗?

是的,在某些情况下您想要这样做是完全合理的。尤其是在您不关心结果的情况下 - 一个示例是不应干扰业务关键代码的分析跟踪操作。

我还能如何运行我不关心的东西?

在许多方面,简单地调用 promise 函数是可行的。您的 del 没有回调可能在这种情况下可以工作,但有些函数不能防止不传递回调,因此您可以传递一个空函数 (.del('key', () => ))。

您确实希望确保您知道它失败,即使您不想中断代码的操作 - 所以请考虑添加 process.on("unhandledRejection', 事件处理程序以明确忽略这些特殊异常或通过以下方式抑制它们:

redisClient.delAsync('key').catch(()=>);

或者最好是这样的:

redisClient.delAsync('key').catch(logErr);

【讨论】:

我觉得这个答案比另一个答案更好地回答了这个问题。 很好的解释。【参考方案3】:

从我目前所做的所有研究来看,我认为这样做是可以的,只要你保证你的功能不是awaiting for 保证一种处理方式如果发生这种情况,它自己的错误。例如,包裹整个函数体的try-catch,就像你在下面的sn-p中看到的asyncFunction一样。

函数是同步抛出还是异步抛出都没有关系。它保证您的mainFunction 无论如何都会完成。这就是这里的重点。

如果你不保证,你必须冒险:

如果它同步抛出,您的主函数将无法完成。 如果它异步抛出,你会得到一个未处理的异常

// THIS IS SOME API CALL YOU DON'T WANT TO WAIT FOR

const mockAPI = () => 
  console.log("From mockAPI");
  return new Promise((resolve,reject) => 
    setTimeout(() => reject("LATE THROW: API ERROR"), 500);
  );
;

// THIS IS THE SOME ASYNC FUNCTION YOU CALL BUT NOT AWAIT FOR

const asyncFunction = async (syncThrow) => 
  try 
    console.log("Async function START");
    if (syncThrow) throw new Error("EARLY THROW");
    await mockAPI();
    console.log("Async function DONE");
  
  catch(err) 
    console.log("From async function catch");
    console.log(err.message || err);
    return;
  
;

// THIS IS YOUR MAIN FUNCTION

const mainFunction = async (syncThrow) => 
  try 
    console.clear();
    console.log("Main function START");
    asyncFunction(syncThrow);
    console.log("Main function DONE <<< THAT'S THE IMPORTANT PART");
  
  catch(err) 
    console.log("THIS WILL NEVER HAPPEN");
    console.log(err);
  
;
<div>
  <button onClick="mainFunction(true)">Sync throw</button>
  <button onClick="mainFunction(false)">Async throw</button>
</div>

【讨论】:

以上是关于我可以在nodejs(ES7)中解雇并忘记一个承诺吗?的主要内容,如果未能解决你的问题,请参考以下文章

何时使用异步 nodejs?

如何在 nodejs 中使用 ES7?

异步 axios 不使用 NODEJS 运行承诺

需要帮助在 NodeJS 中使用 Sinon 存根异步 / 等待承诺

Nodejs 承诺 async/await 不能正常工作

NodeJS - 对承诺函数的无限调用