遍歷 JavaScript 值
返回 js_sys::Iterator
的方法
一些 JavaScript 集合具有用於遍歷其值或鍵的方法
Map::values
Set::keys
- 等等...
這些方法返回 js_sys::Iterator
,它是 JavaScript 物件的 Rust 表示形式,該物件具有一個 next
方法,該方法要么返回遍歷中的下一項,要么指出遍歷已完成,要么拋出錯誤。也就是說,js_sys::Iterator
表示一個實現了 duck-typed JavaScript 遍歷協定的物件。
js_sys::Iterator
可以通過引用(轉換為 js_sys::Iter<'a>
)或通過值(轉換為 js_sys::IntoIter
)轉換為 Rust 迭代器。 Rust 迭代器將產生 Result<JsValue>
類型的項目。如果它產生 Ok(...)
,則 JS 迭代器協定返回了一個元素。如果它產生 Err(...)
,則 JS 迭代器協定拋出了一個異常。
#![allow(unused)] fn main() { use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn count_strings_in_set(set: &js_sys::Set) -> u32 { let mut count = 0; // Call `keys` to get an iterator over the set's elements. Because this is // in a `for ... in ...` loop, Rust will automatically call its // `IntoIterator` trait implementation to convert it into a Rust iterator. for x in set.keys() { // We know the built-in iterator for set elements won't throw // exceptions, so just unwrap the element. If this was an untrusted // iterator, we might want to explicitly handle the case where it throws // an exception instead of returning a `{ value, done }` object. let x = x.unwrap(); // If `x` is a string, increment our count of strings in the set! if x.is_string() { count += 1; } } count } }
遍歷實作了迭代器協定的任何 JavaScript 物件
您可以手動測試物件是否實作了 JS 的 duck-typed 迭代器協定,如果實作了,則將其轉換為 js_sys::Iterator
,您最終可以遍歷它。但是,您不需要手動執行此操作,因為我們將其捆綁為 js_sys::try_iter
函數!
例如,我們可以編寫一個從任何 JS 可迭代物件中收集數字並將它們作為 Array
返回的函式
#![allow(unused)] fn main() { use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn collect_numbers(some_iterable: &JsValue) -> Result<js_sys::Array, JsValue> { let nums = js_sys::Array::new(); let iterator = js_sys::try_iter(some_iterable)?.ok_or_else(|| { "need to pass iterable JS values!" })?; for x in iterator { // If the iterator's `next` method throws an error, propagate it // up to the caller. let x = x?; // If `x` is a number, add it to our array of numbers! if x.as_f64().is_some() { nums.push(&x); } } Ok(nums) } }