【问题标题】:Wrap Datatables rows().every() with Typescript Generators使用 Typescript 生成器包装 Datatables rows().every()
【发布时间】:2018-12-10 08:21:52
【问题描述】:

我想用打字稿生成器/迭代器包装 rows().every 函数

这是我的第一个方法

public * rowIterator1(): IterableIterator<DataTables.RowMethods> {

    var self = this.dataTable;
    this.dataTable.rows().every(function*(rowIdx) {
        console.log(rowIdx);
        let row = self.row(rowIdx);

        yield row;
    });

}

但是调用 yield 行时 every() 函数并没有停止。

下一个方法是使用异步生成器

public async * rowIterator3() {

    yield await new Promise((res) => {
        var self = this;
        this.dataTable.rows().every(function (rowIdx) {
            console.log(rowIdx);
            let row = self.dataTable.row(rowIdx);

            res(row);
        });

    });
}

同样的问题,console.log 说

0 1 2 3 4

调用 yield 时函数没有停止

最后我想要这样的东西:

DtWrapper.rows((row: JQuery, index: number) => {
   do something
}

在摆弄了几个小时之后,这似乎奏效了。虽然使用迭代器不是我所期望的。

public * getRows() {    

        let rowIndexes = this.dataTable.rows().indexes();
        let count = rowIndexes.length;

        for (var i = 0; i < count; i++) {
            let rowIndex = rowIndexes[i];
            let row = this.dataTable.row(rowIndex);
            yield $(row.node());
        }
    }

    public test() {


        let t = this.getRows(true);

        let a = t.next();
        a = t.next();
        a = t.next();

}

【问题讨论】:

  • every 的思想/算法是“取每个元素,直到迭代器用尽”。如果您想一次迭代一个元素,请使用for (... of ...)(或直接使用迭代器)。
  • 你到底想达到什么目的?
  • 我想将数据表组件包装在一个包装类中。这个 Wrapper 应该有一个迭代器函数来迭代表行。迭代器函数应该只返回节点(JQuery)和行的索引,而不是行对象本身。

标签: typescript datatables iterator datatables-1.10


【解决方案1】:

当您使用 next() 调用迭代器时,迭代器将在每次 yield 时有效地停止执行。

every() 内置 JS 将接受一个迭代器并尝试耗尽它(调用 next() 直到迭代器将迭代器标记为完成)。

要使用迭代器(是否由生成器函数创建),通常的方法是在for (... of ...) 中使用它。这将有效地获取每个元素并独立处理它,在每次迭代时适当地调用next()

【讨论】:

  • 谢谢,需要设置 "downlevelIteration": true,在 tsconfig 中,现在 for of 正在工作
  • 是否可以这样构建生成器,因为生成器没有值,所以 for (... of ...) 循环将跳过循环?
  • @DanielR 如果生成器没有生成任何值并立即完成,那么 for ... of 应该表现得好像您正在迭代一个空数组。这不是开箱即用的吗?
  • 是的,但我有另一个生成器,它通过 yield* 传递生成器。但在某些情况下我需要不经过生成器就返回
  • @DanielR 我建议针对这一特定需求编写另一个问题,并解释您要在全球范围内实现的目标(包括为什么您认为您需要“在不通过生成器的情况下返回” ,目前我还不清楚)
【解决方案2】:

我开发了一个适合我的解决方案。 (感谢@Pac0 提供正确的输入)

function* func1() {
  yield 42;
  yield 2;
}

function* func2(param) {
    if (param)
    return;
  yield* func1();
}



for (var value of func2(true))
{
    console.log(value);
}
console.log("finished true");

for (var value of func2(false))
{
    console.log(value);
}
console.log("finished false");

这是一个工作小提琴https://jsfiddle.net/qu9ksxpd/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-05
    • 2021-07-14
    • 1970-01-01
    • 2019-05-15
    • 2013-04-09
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多