D. *_*ick 5 promise async-await typescript union-types
我正在用打字稿构建一个 API,一些控制器操作可以同步,而另一些则不能。我想指定一个响应类型,如下所示:
type ActionResult =IHttpActionResult | Promise<IHttpActionResult>;
Run Code Online (Sandbox Code Playgroud)
然后,当我构建操作时,当它们变得基于承诺时,我可以只添加异步并完成它。
但是,打字稿抱怨“异步函数或方法的返回类型必须是全局 Promise 类型”。
为什么异步函数不能返回 的并集T | Promise<T>?
这是一个例子:
type StringPromise = Promise<string>;
// These two work as you'd expect
async function getHello(): Promise<string> {
return 'hello';
}
async function getGoodbye(): StringPromise {
return 'goodbye';
}
type StringyThingy = string | Promise<string>;
// the next two work as you would expect them to
function getHoorah(): StringyThingy {
return 'hoorah!';
}
function getWahoo(): StringyThingy {
return new Promise(resolve => resolve('wahoo'));
}
// This one results in the error:
// "the return type of an async function or method must be the global Promise type."
async function getSadface(): StringyThingy {
return ':(';
}
Run Code Online (Sandbox Code Playgroud)
以下是上述代码的一些示例输出:
getHello().then(console.log);
getGoodbye().then(console.log);
console.log(getHoorah());
// The library I'm using is probably using typeguards for this
// I'd imagine
const wahoo = getWahoo();
if (typeof(wahoo) === 'string') {
console.log(wahoo);
} else {
wahoo.then(console.log);
}
Run Code Online (Sandbox Code Playgroud)
该async符号是语法糖:“此函数将始终返回一个承诺。”
即使你这样声明:
const foo = async() => 3;
Run Code Online (Sandbox Code Playgroud)
它基本上与以下相同(尽管更严格):
const foo = () => new Promise(resolve => resolve(3));
Run Code Online (Sandbox Code Playgroud)
或作为:
const foo = () => Promise.resolve(3);
Run Code Online (Sandbox Code Playgroud)
所有这些示例都会返回一个 Promise。
主要区别在于,“普通”函数可以返回 Promise 和其他类型,但一旦async使用它,它总是会返回一个 Promise。
即使 Promise 立即解析,函数也无法按照设计不返回 Promise。async
你必须等待它/然后使用它。
mozilla 的 JavaScript 参考中关于 async 关键字的内容也有说明:
async 函数声明定义了一个异步函数,该函数返回一个 AsyncFunction 对象。异步函数是通过事件循环异步操作的函数,使用隐式 Promise 返回其结果。但使用异步函数的代码的语法和结构更像使用标准同步函数。
特别是关于返回类型:
一个 Promise,将使用异步函数返回的值进行解析,或者通过从异步函数内部抛出未捕获的异常来拒绝。
考虑到这一点,我建议您将 API 设置async为默认值。如果你的某些行为是同步的,对于外界来说并不重要。在这种情况下,您可以立即解决承诺。不需要你的type StringyThingy = string | Promise<string>;
输入 againstPromise<string>并让 async 为您处理包装到 Promise 中,或者在真正的异步用例中实际返回其他 Promise。这样您就不必检查 Promise 的实例,但您将以相同的方式处理异步/同步分支。
如果你真的想要union类型(我真的不推荐这个),那么你就必须放弃关键字的使用async。
您可以定义返回任一类型的普通函数:
const foo = (x:number): Promise<number>|number => {
if(x >=0) {
return new Promise(resolve => resolve(x));
} else {
return x;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3612 次 |
| 最近记录: |