Js 迭代器高级用法

Js 迭代器高级用法

JavaScript中的迭代器是一种强大的工具,可以用于遍历和处理集合中的元素。迭代器提供了许多高级用法,可以更加灵活和有效地处理数据。在本篇文章中,将介绍15个用于迭代器的高级用法,以便开发者更好地理解和应用这一概念。

1. 自定义迭代器

使用Symbol.iterator可以为对象定义自定义迭代器。

javascript 复制代码
const myObject = {
    data: ['Apple', 'Banana', 'Orange'],
    [Symbol.iterator]() {
        let index = 0;

        return {
            next: () => {
                if (index < this.data.length) {
                    return { value: this.data[index++], done: false };
                } else {
                    return { done: true };
                }
            }
        };
    }
};

for (const item of myObject) {
    console.log(item);
}
// 输出: 'Apple', 'Banana', 'Orange'

2. 生成迭代器

可以使用Generator函数生成一个迭代器。

javascript 复制代码
function* myGenerator() {
    yield 'Apple';
    yield 'Banana';
    yield 'Orange';
}

const generator = myGenerator();

console.log(generator.next().value); // 输出: 'Apple'
console.log(generator.next().value); // 输出: 'Banana'
console.log(generator.next().value); // 输出: 'Orange'

3. 双向迭代器

使用for...of语句可以双向迭代器(如SetMap)中的元素。

javascript 复制代码
const mySet = new Set(['Apple', 'Banana', 'Orange']);

for (const item of mySet) {
    console.log(item);
}
// 输出: 'Apple', 'Banana', 'Orange'

4. 迭代器链

多个迭代器可以链接起来形成一个大的迭代器链。

javascript 复制代码
const fruits = ['Apple', 'Banana', 'Orange'];
const iterator1 = fruits[Symbol.iterator]();
const iterator2 = fruits[Symbol.iterator]();
const combinedIterator = {
    next() {
        const { value, done } = iterator1.next();
        if (!done) {
            return { value, done };
        } else {
            return iterator2.next();
        }
    }
};

for (const item of combinedIterator) {
    console.log(item);
}
// 输出: 'Apple', 'Banana', 'Orange'

5. 取部分元素

使用slice方法可以从迭代器中取出部分元素。

javascript 复制代码
const numbers = [1, 2, 3, 4, 5];
const iterator = numbers[Symbol.iterator]();
const slicedIterator = {
    next() {
        const { value, done } = iterator.next();
        if (value === 3) {
            return { value, done };
        }
        if (!done) {
            return this.next();
        } else {
            return { done };
        }
    }
};

for (const item of slicedIterator) {
    console.log(item);
}
// 输出: 3

6. 跳过部分元素

使用skip方法可以跳过迭代器中的部分元素。

javascript 复制代码
const numbers = [1, 2, 3, 4, 5];
const iterator = numbers[Symbol.iterator]();
const skippedIterator = {
    next() {
        const { value, done } = iterator.next();
        if (value === 3) {
            return iterator.next();
        }
        return { value, done };
    }
};

for (const item of skippedIterator) {
    console.log(item);
}
// 输出: 1, 2, 4, 5

7. 过滤元素

使用filter方法可以筛选迭代器中符合条件的元素。

javascript 复制代码
const numbers = [1, 2, 3, 4, 5];
const iterator = numbers[Symbol.iterator]();
const filteredIterator = {
    next() {
        let { value, done } = iterator.next();
        while (!done && value % 2 === 0) {
            ({ value, done } = iterator.next());
        }
        return { value, done };
    }
};

for (const item of filteredIterator) {
    console.log(item);
}
// 输出: 1, 3, 5

8. 映射元素

使用map方法可以对迭代器中的元素进行映射操作。

javascript 复制代码
const numbers = [1, 2, 3, 4, 5];
const iterator = numbers[Symbol.iterator]();
const mappedIterator = {
    next() {
        const { value, done } = iterator.next();
        if (!done) {
            return { value: value * 2, done };
        } else {
            return { done };
        }
    }
};

for (const item of mappedIterator) {
    console.log(item);
}
// 输出: 2, 4, 6, 8, 10

9. 合并迭代器

使用zip方法可以合并多个迭代器为一个。

javascript 复制代码
function* zip(iterators) {
    const iteratorsArr = iterators.map(iterator => iterator[Symbol.iterator]());
    while (true) {
        const results = iteratorsArr.map(iterator => iterator.next());
        if (results.some(result => result.done)) {
            return;
        }
        yield results.map(result => result.value);
    }
}

const numbers = [1, 2, 3];
const letters = ['a', 'b', 'c'];
const zipped = zip([numbers, letters]);

for (const item of zipped) {
    console.log(item);
}
// 输出: [1, 'a'], [2, 'b'], [3, 'c']

10. 反向迭代

使用reverse方法可以反向迭代一个迭代器。

javascript 复制代码
function* reverseIterator(iterable) {
    const array = Array.from(iterable);
    for (let i = array.length - 1; i >= 0; i--) {
        yield array[i];
    }
}

const numbers = [1, 2, 3, 4, 5];
const reversed = reverseIterator(numbers);

for (const item of reversed) {
    console.log(item);
}
// 输出: 5, 4, 3, 2, 1

11. 迭代倒计时

使用迭代器可以实现倒计时的效果。

javascript 复制代码
function* countDown(from) {
    while (from >= 0) {
        yield from;
        from--;
    }
}

const countdownIterator = countDown(5);

const countdownInterval = setInterval(() => {
    const { value, done } = countdownIterator.next();
    if (done) {
        clearInterval(countdownInterval);
    } else {
        console.log(value);
    }
}, 1000);

12. 同步迭代异步操作

使用reduce方法可以同步迭代一个异步操作的集合。

javascript 复制代码
const urls = ['url1', 'url2', 'url3'];

async function asyncOperation(url) {
    // 异步操作
    return url;
}

const result = urls.reduce(async (accumulatorPromise, url) => {
    const accumulator = await accumulatorPromise;
    const value = await asyncOperation(url);
    accumulator.push(value);
    return accumulator;
}, Promise.resolve([]));

result.then(console.log);
// 输出: ['url1', 'url2', 'url3']

13. 合并异步操作结果

使用Promise.all方法可以将多个异步操作的结果进行合并。

javascript 复制代码
const urls = ['url1', 'url2', 'url3'];

async function asyncOperation(url) {
    // 异步操作
    return url;
}

const result = await Promise.all(urls.map(asyncOperation));

console.log(result);
// 输出: ['url1', 'url2', 'url3']

14. 处理异步操作异常

在迭代异步操作时,可以使用try...catch语句处理异常。

javascript 复制代码
const urls = ['url1', 'url2', 'url3'];

async function asyncOperation(url) {
    if (url === 'url2') throw new Error('Operation failed.');
    return url;
}

async function processUrls(urls) {
    for (const url of urls) {
        try {
            const result = await asyncOperation(url);
            console.log(result);
        } catch (error) {
            console.error(error);
        }
    }
}

processUrls(urls);

15. 并行处理异步操作

通过使用Promise.all方法和map方法,可以并行处理一组异步操作。

javascript 复制代码
const urls = ['url1', 'url2', 'url3'];

async function asyncOperation(url) {
    // 异步操作
    return url;
}

async function processUrls(urls) {
    const results = await Promise.all(urls.map(asyncOperation));
    console.log(results);
}

processUrls(urls);
// 输出: ['url1', 'url2', 'url3']
相关推荐
M_emory_6 分钟前
解决 git clone 出现:Failed to connect to 127.0.0.1 port 1080: Connection refused 错误
前端·vue.js·git
Ciito9 分钟前
vue项目使用eslint+prettier管理项目格式化
前端·javascript·vue.js
成都被卷死的程序员42 分钟前
响应式网页设计--html
前端·html
mon_star°1 小时前
将答题成绩排行榜数据通过前端生成excel的方式实现导出下载功能
前端·excel
Zrf21913184551 小时前
前端笔试中oj算法题的解法模版
前端·readline·oj算法
文军的烹饪实验室2 小时前
ValueError: Circular reference detected
开发语言·前端·javascript
Martin -Tang3 小时前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发3 小时前
解锁微前端的优秀库
前端
王解4 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
我不当帕鲁谁当帕鲁4 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis