我可以触发并忘记 nodejs (ES7) 中的承诺吗?
Can I fire and forget a promise in nodejs (ES7)?
我想 运行 这段代码与 babel:
redisClientAsync.delAsync('key');
return await someOtherAsyncFunction();
在没有 await 第一行的异步函数中。这样可以吗?
我还能如何 运行 我不关心的事情?
我可以在没有回调的情况下触发非承诺函数 del('key',null) 吗?
是的,你可以这样做,它会运行 两个异步函数并行。您刚刚创建了一个承诺并将其丢弃。
然而,这意味着当承诺被拒绝时,您不会注意到。你只会 如果不处理它会导致你的进程崩溃。
Is this OK? How can I run something that I don't care?
应该是不对吧。如果您真的不在乎,那您一开始就没有 运行 它。所以你应该清楚明确地知道你关心什么(以及不关心什么):
- 你要等吗? (副作用)
- 需要结果吗?
- 你想捕捉异常吗?
如果你只想等待而不关心结果值,你可以很容易地把结果扔掉:
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;
inside an async function without await the first line. is this OK?
是的,在某些情况下您想要这样做是完全合理的。尤其是在您不关心结果的情况下 - 一个示例是不应干扰业务关键代码的分析跟踪操作。
how else can I run something that I don't care?
在许多方面,但只需调用 promise 函数即可。在这种情况下,没有回调的 del
可能会起作用,但某些函数无法防止不传递回调,因此您可以传递一个空函数 (.del('key', () => {})
).
但是您确实想要确保您知道它失败了,即使您不想中断代码的运行 - 所以请考虑添加一个 process.on("unhandledRejection',
事件处理程序以显式忽略这些特定异常或通过以下方式抑制它们:
redisClient.delAsync('key').catch(()=>{});
或者最好是这样的:
redisClient.delAsync('key').catch(logErr);
根据我迄今为止所做的所有研究,我认为这样做很好,只要你保证你没有await
保证 一种在发生这种情况时处理自身错误的方法。例如,try-catch
包装了整个函数体,就像您在下面的 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>
我想 运行 这段代码与 babel:
redisClientAsync.delAsync('key');
return await someOtherAsyncFunction();
在没有 await 第一行的异步函数中。这样可以吗?
我还能如何 运行 我不关心的事情?
我可以在没有回调的情况下触发非承诺函数 del('key',null) 吗?
是的,你可以这样做,它会运行 两个异步函数并行。您刚刚创建了一个承诺并将其丢弃。
然而,这意味着当承诺被拒绝时,您不会注意到。你只会
Is this OK? How can I run something that I don't care?
应该是不对吧。如果您真的不在乎,那您一开始就没有 运行 它。所以你应该清楚明确地知道你关心什么(以及不关心什么):
- 你要等吗? (副作用)
- 需要结果吗?
- 你想捕捉异常吗?
如果你只想等待而不关心结果值,你可以很容易地把结果扔掉:
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;
inside an async function without await the first line. is this OK?
是的,在某些情况下您想要这样做是完全合理的。尤其是在您不关心结果的情况下 - 一个示例是不应干扰业务关键代码的分析跟踪操作。
how else can I run something that I don't care?
在许多方面,但只需调用 promise 函数即可。在这种情况下,没有回调的 del
可能会起作用,但某些函数无法防止不传递回调,因此您可以传递一个空函数 (.del('key', () => {})
).
但是您确实想要确保您知道它失败了,即使您不想中断代码的运行 - 所以请考虑添加一个 process.on("unhandledRejection',
事件处理程序以显式忽略这些特定异常或通过以下方式抑制它们:
redisClient.delAsync('key').catch(()=>{});
或者最好是这样的:
redisClient.delAsync('key').catch(logErr);
根据我迄今为止所做的所有研究,我认为这样做很好,只要你保证你没有await
保证 一种在发生这种情况时处理自身错误的方法。例如,try-catch
包装了整个函数体,就像您在下面的 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>