简体   繁体   English

如何在 dart 的外部范围内更改变量的值?

[英]How can I change the value of a variable in outer scope in dart?

 Product getProduct(QueryDocumentSnapshot doc) {
    Product product;
    _firestore
        .collection('products')
        .where('isAvailable', isEqualTo: true)
        .snapshots(includeMetadataChanges: true)
        .map(
          (event) => event.docs.map(
            (document) {
              if (document.id == doc.data()['id']) {
                product = Product.fromJson(document.data());
              }
            },
          ),
        );
    return product;
  }

In the code above, each time the function is called, I want from it to override the value of product in line 2 , the desired operation of overriding is being done in the 11th line, but it always returns Null , so how can I assign a value to it from the inner function?在上面的代码中,每次调用该函数时,我想从中覆盖第2行中product的值,所需的覆盖操作在第11行中完成,但它始终返回Null ,那么我该如何分配来自内部函数的值?

Data is loaded from Firestore asynchronously.数据从 Firestore 异步加载。 While this is going on, your main code continues to run (so that the user can continue using the app).在此过程中,您的主代码会继续运行(以便用户可以继续使用该应用程序)。 It's easiest to see what this means by adding some logging code:通过添加一些日志记录代码,最容易看出这意味着什么:

print('Before starting to load data');
_firestore
    .collection('products')
    .where('isAvailable', isEqualTo: true)
    .snapshots(includeMetadataChanges: true)
    .map(
        print('Got data');
    );
print('After starting to load data');

If you run this code, it prints:如果您运行此代码,它会打印:

Before starting to load data在开始加载数据之前

After starting to load data开始加载数据后

Got data有数据

Got data有数据

... ...

This is probably not what you expected, but explains perfectly why your calls to getProduct() don't get back any data: by the time your return product;这可能不是您所期望的,但完美地解释了为什么您对getProduct()调用没有取回任何数据:当您return product; runs, the product = Product.fromJson(document.data());运行, product = Product.fromJson(document.data()); hasn't been called yet.还没有被调用。


A common solution for this is to return a Future from the method, which then resolves to the value once it is loaded.一个常见的解决方案是从该方法返回一个Future ,然后在加载后解析为该值。

That'd look something like this (typos possible, as I haven't run this code):看起来像这样(可能有错别字,因为我还没有运行此代码):

  Future<Product> getProduct(QueryDocumentSnapshot doc) async {
    Product product;
    var snapshot = await _firestore
        .collection('products')
        .where('isAvailable', isEqualTo: true)
        .get();
    snapshot.docs.map((document) {
      if (document.id == doc.data()['id']) {
        product = Product.fromJson(document.data());
      }
    })
    return product;
  }

Note that I also use get() instead of snapshots(...) above, as you're only looking to return a value once, instead of continuing to listen to updates.请注意,我还使用get()而不是上面的snapshots(...) ,因为您只想返回一次值,而不是继续收听更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM