return 方法在迭代器/异步迭代器中如何使用?
How is the return method used in iterators / async iterators?
MDN states that async iterators have a return method
const asyncIterable = {
[Symbol.asyncIterator]() {
let i = 0;
return {
next() {
const done = i === LIMIT;
const value = done ? undefined : i++;
return Promise.resolve({ value, done });
},
return() {
// This will be reached if the consumer called 'break' or 'return' early in the loop.
return { done: true };
}
};
}
};
但是,异步迭代器的 Typescript 定义需要 return
方法来
- 接受可选值
- return
{value: someValue, done: true}
,而 MDN 不这样做。
这是 TS 定义:
interface AsyncIterator<T, TReturn = any, TNext = undefined> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
return?(value?: TReturn | PromiseLike<TReturn>): Promise<IteratorResult<T, TReturn>>;
throw?(e?: any): Promise<IteratorResult<T, TReturn>>;
}
有人可以解释这个差异吗? return
是如何工作的?
MDN,无论多么权威,在语言规范方面都不是真实的来源。 TypeScript 遵循 ECMAScript spec, in this instance, the definition of the AsyncIterator
interface (as @@asyncIterator
well-known symbol 是 returns 和 AsyncIterator
).
的方法
Table规范的76和77分别提供了接口的必需和可选属性:next
、return
和throw
。我们对规范对第二个参数的说明感兴趣:
The returned promise will fulfill with an IteratorResult
object which will typically have a "done" property whose value is true, and a "value" property with the value passed as the argument of the return method. However, this requirement is not enforced.
请注意第一句的最后一部分——这里是 TReturn | PromiseLike<TReturn>
的来源。然后注意第二句——这就是为什么参数是可选的。
从上面也可以看出,return
方法 returns 一个实现 IteratorResult
接口的对象,它被定义为具有 done
布尔值和value
不受限制 属性。这两个属性都不被认为是可选的,但每个属性在规范的 table 78 中都有一个注释,允许缺少任何一个。
但是,IteratorReturnResult
(IteratorResult
联合类型的成员)的 TypeScript 定义没有考虑这些注释并根据需要标记这些属性:
interface IteratorReturnResult<TReturn> {
done: true;
value: TReturn;
}
这已在源存储库的 issue #8938 中受到质疑,团队推理如下:
As noted by @ivogabe we need to have boolean literal types, to be able to model this one accurately.
并随后关闭以支持 issue #2983 fixed by PR #30790,而最初的请求似乎从裂缝中溜走。
MDN states that async iterators have a return method
const asyncIterable = {
[Symbol.asyncIterator]() {
let i = 0;
return {
next() {
const done = i === LIMIT;
const value = done ? undefined : i++;
return Promise.resolve({ value, done });
},
return() {
// This will be reached if the consumer called 'break' or 'return' early in the loop.
return { done: true };
}
};
}
};
但是,异步迭代器的 Typescript 定义需要 return
方法来
- 接受可选值
- return
{value: someValue, done: true}
,而 MDN 不这样做。
这是 TS 定义:
interface AsyncIterator<T, TReturn = any, TNext = undefined> {
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
return?(value?: TReturn | PromiseLike<TReturn>): Promise<IteratorResult<T, TReturn>>;
throw?(e?: any): Promise<IteratorResult<T, TReturn>>;
}
有人可以解释这个差异吗? return
是如何工作的?
MDN,无论多么权威,在语言规范方面都不是真实的来源。 TypeScript 遵循 ECMAScript spec, in this instance, the definition of the AsyncIterator
interface (as @@asyncIterator
well-known symbol 是 returns 和 AsyncIterator
).
Table规范的76和77分别提供了接口的必需和可选属性:next
、return
和throw
。我们对规范对第二个参数的说明感兴趣:
The returned promise will fulfill with an
IteratorResult
object which will typically have a "done" property whose value is true, and a "value" property with the value passed as the argument of the return method. However, this requirement is not enforced.
请注意第一句的最后一部分——这里是 TReturn | PromiseLike<TReturn>
的来源。然后注意第二句——这就是为什么参数是可选的。
从上面也可以看出,return
方法 returns 一个实现 IteratorResult
接口的对象,它被定义为具有 done
布尔值和value
不受限制 属性。这两个属性都不被认为是可选的,但每个属性在规范的 table 78 中都有一个注释,允许缺少任何一个。
但是,IteratorReturnResult
(IteratorResult
联合类型的成员)的 TypeScript 定义没有考虑这些注释并根据需要标记这些属性:
interface IteratorReturnResult<TReturn> {
done: true;
value: TReturn;
}
这已在源存储库的 issue #8938 中受到质疑,团队推理如下:
As noted by @ivogabe we need to have boolean literal types, to be able to model this one accurately.
并随后关闭以支持 issue #2983 fixed by PR #30790,而最初的请求似乎从裂缝中溜走。