遍歷 JavaScript 值

返回 js_sys::Iterator 的方法

一些 JavaScript 集合具有遍歷其值或鍵的方法

這些方法返回 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_variables)]
#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_variables)]
#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)
}
#}