无法将数组分配给打字稿中的另一个数组

Posted

技术标签:

【中文标题】无法将数组分配给打字稿中的另一个数组【英文标题】:not able to assign an array to another array in typescript 【发布时间】:2016-11-28 13:07:27 【问题描述】:

我已将 kitems 定义为 private kitems:any[];在课堂里。但是无法使用 this.kitems = items; 为其分配任何值当我执行 console.log(this.kitems) 时,我得到一个空数组。

createprofile() 
    this._UserRef.on("value", function(snapshot) 
        let items = [];
        snapshot.forEach(function(childSnapshot) 
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        );
        console.log(items[0].key);
        this.kitems = items;
    .bind(this));
    console.log(this.kitems);

【问题讨论】:

我很确定这是因为 on 函数是异步的,并且您正在查看的控制台日志在它开始运行之前就已完成。 :) 尝试调试它;) 【参考方案1】:

当您将侦听器附加到 Firebase 数据库(在您的情况下为 on())时,它开始从数据库加载数据。由于这可能需要一些时间,因此 javascript 代码会继续执行,并且您的代码会打印空数组。然后,当数据从服务器可用时,将调用您的回调并将数据添加到数组中。

如果您添加一些日志语句,这通常是最容易遵循的:

createprofile() 
    console.log("Start listening");
    this._UserRef.on("value", function(snapshot) 
        console.log("Got value");
        let items = [];
        snapshot.forEach(function(childSnapshot) 
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        );
        this.kitems = items;
    .bind(this));
    console.log("After listener");

输出将是:

开始收听

听者之后

获得价值

这可能不是您所期望的。但它是现代基于互联网的编程的本质所固有的。大多数 API 都会遇到这种行为。

一个常见的技巧是在处理这种所谓的异步 API 时以不同的方式构建代码。在传统编程中,您经常编写“先获取 A,然后执行 B”的代码。使用异步 API,将其框架为“当我们得到 A 时,我们就用它来做 B”。在您的代码中,这意味着您将需要风筝的代码移到回调函数中:

createprofile() 
    this._UserRef.on("value", function(snapshot) 
        let items = [];
        snapshot.forEach(function(childSnapshot) 
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        );
        this.kitems = items;
        console.log(this.kitems);
    .bind(this));

并非只有在服务器返回数据后才会记录风筝。更好的是:Firebase 数据库会同步数据,因此您的回调将在每次数据更改时运行

由于将需要风筝的代码放入回调中可能会损害可重用性,因此通常将回调函数传递到数据加载代码中。

createProfileAndThen(callback) 
    this._UserRef.on("value", function(snapshot) 
        let items = [];
        snapshot.forEach(function(childSnapshot) 
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        );
        this.kitems = items;
        callback(this.kitems);
    .bind(this));


createProfileAndThen(function(kitems) 
    console.log(kitems);
);

这与您传递给 Firebase 的 on() 函数的回调非常相似,但随后针对您的用例进行了定制。

【讨论】:

【参考方案2】:

在您的代码中,您使用的是this。你很可能有错误的this。使用箭头函数:

createprofile = () => 
    this._UserRef.on("value", (snapshot) => 
        let items = [];
        snapshot.forEach((childSnapshot) => 
            let item = childSnapshot.val();
            item['key'] = childSnapshot.key;
            items.push(item);
        );
    console.log(items[0].key);
    this.kitems = items;
    );
console.log(this.kitems);

更多

https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html

并且尽量不要使用bind : https://basarat.gitbooks.io/typescript/content/docs/tips/bind.html

【讨论】:

嗨@basarat 如果我在快照函数中使用console.log,就在语句this.kitems = items 之后,我得到了this.kitems 项。但是,如果我执行 console.log(this.kitems) 在该函数之外,我会得到一个空数组。

以上是关于无法将数组分配给打字稿中的另一个数组的主要内容,如果未能解决你的问题,请参考以下文章

无法从打字稿中的 json 对象获取数组响应

循环将新记录添加到打字稿中的数组[关闭]

如何将firebase REST API响应转换为打字稿中的数组?

如何将这些对象转换为打字稿中的数组

如何将 PHP 数组分配给 jQuery 数组? [复制]

打字稿中的数组