Pix*_*aul 33 javascript asynchronous node.js promise async-await
使用async/await
和.then().catch()
一起使用是否有任何危害,例如:
async apiCall(params) {
var results = await this.anotherCall()
.then(results => {
//do any results transformations
return results;
})
.catch(error => {
//handle any errors here
});
return results;
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*cky 48
不想复活死者,但想指出与链条await
一起使用then
意味着结果:
const x = await someAsyncFn().then(() => doSomeLogging());
Run Code Online (Sandbox Code Playgroud)
的值x
被指定为返回值 .then
(即undefined
,如果doSomeLogging
为空),这对我来说不是非常直观。
sli*_*wp2 26
我总是使用async/await
and.catch()
而不是使用 async/await
andtry/catch
来紧凑地编写代码。
async function asyncTask() {
throw new Error('network')
}
async function main() {
const result = await asyncTask().catch(error => console.error(error));
console.log('result:', result)
}
main();
Run Code Online (Sandbox Code Playgroud)
如果你想在错误发生时得到一个回退值,你可以忽略错误并在.catch()
方法内部返回一个值
async function asyncTask() {
throw new Error('network')
}
async function main() {
const result = await asyncTask().catch(_ => 'fallback value');
console.log('result:', result)
}
main();
Run Code Online (Sandbox Code Playgroud)
Shu*_*ubh 19
异步函数可以包含一个 await 表达式,该表达式暂停异步函数的执行并等待传递的 Promise 的解析,然后恢复异步函数的执行并返回解析的值。
正如您从下面的示例中看到的,您可以使用两种方法来处理等待结果和错误,关键字 await 使 JavaScript 等待,直到该承诺解决并返回其结果(您从已解决的承诺中获得一种)。因此,没有任何危害(我不完全理解你在这里所说的伤害)。
function returnpromise(val) {
return new Promise((resolve, reject) => {
if (val > 5) {
resolve("resolved"); // fulfilled
} else {
reject("rejected"); // rejected
}
});
}
//This is how you handle errors in await
async function apicall() {
try {
console.log(await returnpromise(5))
} catch (error) {
console.log(error)
}
}
async function apicall2() {
let data = await returnpromise(2).catch((error) => {
console.log(error)
})
}
apicall2();
apicall();
Run Code Online (Sandbox Code Playgroud)
如需进一步参考,请查看- MDN DOCS
Pet*_*uan 12
我认为混合使用 async/await + then 不是一个好主意。尤其是当你专注于 async func 的资源时,混合使用会带来一些悄然扭曲你的资源的风险。
例子:
const res = await fetchData().then(()=>{return "something else"}).catch((err)=>{});
console.log(res); // not expected res data but something else
Run Code Online (Sandbox Code Playgroud)
所以,混合使用是危险的,顺便说一下,它会损害阅读代码。
ggo*_*len 12
我认为整个线程对于“伤害”的含义存在一些困惑。如果你将伤害定义为(仅仅)“OP 的确切代码运行正常吗?”,那么它就没有伤害。
然而,如果你将危害定义为“这是一种难以阅读、容易出错的反模式,往往会导致错误,并且从来没有真正必要诉诸”,那么它确实是有害的。
Stack Overflow 上有无数的问题,其中 OP 混合在一起.then
并await
最终出现了错误。我选择了一些内容包含在这篇文章的底部。
作为一个简单的经验法则,永远不要将and组合在一个函数中await
then
。最好的情况是,它比使用其中之一更难阅读,最坏的情况是,它隐藏了一个错误,通常与错误处理有关。
一般来说,更喜欢async
/await
而不是.then
。如果您很难决定何时使用哪个,请随意更进一步并.then
完全避免.catch
。
也就是说,我喜欢偶尔使用.then
它,当涉及错误处理时,它可以稍微不那么冗长,并且不需要访问无法轻松通过链传递的对象的状态:
fetch("https://www.example.com")
.then(response => {
if (!response.ok) {
throw Error(response.statusText);
}
return response.json();
)
.then(data => console.log(data))
.catch(err => console.error(err));
Run Code Online (Sandbox Code Playgroud)
对我来说似乎比以下更干净:
(async () => {
try {
const response = await fetch("https://www.example.com");
if (!response.ok) {
throw Error(response.statusText);
}
console.log(response.json());
}
catch (err) {
console.error(err);
}
})();
Run Code Online (Sandbox Code Playgroud)
使用 top-level await
,底层代码变得更有吸引力,尽管在实践中,您通常编写一个函数。
我同意这个答案给出的一个例外,即偶尔.catch
在await
链上使用以避免有点难看的try
/ catch
。
以下是此功能何时有用的示例:
const fs = require("node:fs/promises");
const exists = async pathName =>
!!(await fs.stat(pathName).catch(() => false));
Run Code Online (Sandbox Code Playgroud)
可能比///async
版本await
更好try
:catch
const exists = async pathName => {
try {
await fs.stat(pathName);
return true;
}
catch (err) {
return false;
}
};
Run Code Online (Sandbox Code Playgroud)
...或者也许不取决于你是否觉得这个catch
版本太聪明了。
请注意,这里没有.then
andawait
混合,只是.catch
而不是try
/ except
。这里起作用的一般启发是“更平坦更好”(.catch
比try
/更平坦catch
并且await
比 更平坦.then
)。
(是的,这个例子有点人为,因为有一种非常干净的方法可以单独使用.then
/.catch
来完成这个特定的任务,但是该模式可能会不时出现在其他上下文中)
如果有任何疑问,请遵守“绝不混合”的规则。
await
正如所承诺的,这里是我所看到的一小部分由混合和then
(加上一些其他承诺反模式)引起的混乱的示例:
以及相关主题:
Abd*_*ssi 10
如果您使用 Async/await,则不需要链接,只需.then()
将返回的结果存储resolve()
在变量中(response
在示例中),但如果您想处理错误,则必须尝试/捕获代码:
async function f() {
try {
let response = await fetch('http://no-such-url');
} catch(err) {
alert(err); // TypeError: failed to fetch
}
}
Run Code Online (Sandbox Code Playgroud)
在你的承诺中使用:
throw new Error("oops!");
或者
Promise.reject(new Error("Whoops!"));
归档时间: |
|
查看次数: |
25548 次 |
最近记录: |