如何使用Await等待值

时间:2019-03-27 02:43:49

标签: flutter

我正在使用Flutter将图像上传到Firebase,并具有一个提交表单时触发的函数commit()。提交时,我确认提交的准确性,并调用uploadFile函数将指定的图像上传到Firebase存储并返回URL(我将其设置为urlForPost)。

我想等待urlForPost值的设置,然后触发将其上传到Firebase的其余commit()函数。当前,它为urlForPost返回一个空值。如何等待uploadFile()函数加载,以防止urlForPost为null?

void submit() async {
    // First validate form.
    if (this._formKey.currentState.validate()) {
      _formKey.currentState.save();// Save our form now.

      final urlForPost = await uploadFile();


      Firestore.instance
          .collection('posts')
          .document(documentName)
          .collection('collection')
          .add({
        'user': widget.userPoster,
        'post': _data.post,
        'url': urlForPost,
        'timePosted': Timestamp.now(),
      });

      Firestore.instance.collection('current_goals').document(widget.userPoster).collection(widget.goalType).document(widget.goalID).updateData(
        {
          'complete': true,
        }
      );


      Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => Home()));    }
  }
  String downloadUrl;

  Future<String> uploadFile() async {

    final String rand1 = "${new Random().nextInt(10000)}";
    final String rand2 = "${new Random().nextInt(10000)}";
    final String rand3 = "${new Random().nextInt(10000)}";
    final StorageReference ref = FirebaseStorage.instance.ref().child('${rand1}_${rand2}_${rand3}.jpg');
     await ref.putFile(widget.selectedImage).onComplete.then((val) {
      val.ref.getDownloadURL().then((val) {
        print(val);
        downloadUrl = val; //Val here is Already String
      });
    });

     return downloadUrl;

  }

1 个答案:

答案 0 :(得分:0)

您也可以将uploadFile的方法更改为await进行上传。

您使用await使异步调用同步。但是,如果将其与.then()方法混合使用,则有可能使它的某些部分无意间异步。

  Future<String> uploadFile() async {
    final String rand1 = "${new Random().nextInt(10000)}";
    final String rand2 = "${new Random().nextInt(10000)}";
    final String rand3 = "${new Random().nextInt(10000)}";

    // you don't need {} if it's a simple statement, use $stringvar and ${value.toString}
    final StorageReference ref = FirebaseStorage.instance.ref().child('$rand1_$rand2_$rand3.jpg');

    StorageUploadTask task = ref.putFile(imageFile);
    var downloadUrl = await (await task.onComplete).ref.getDownloadURL();
    debugPrint("downloadUrl=$downloadUrl");
    return downloadUrl.toString();
  }

只是与您的原始问题无关的建议

使用3个随机数,随着时间的推移您可能会发生冲突。考虑使用UUID package,发生碰撞的机会大大减少。 :)

  Future<String> uploadFile() async {
    final String uuid = uuid.v4(); // v4 is random, v1 is time-based

    final StorageReference ref = FirebaseStorage.instance.ref().child('$uuid.jpg');

    StorageUploadTask task = ref.putFile(imageFile);
    var downloadUrl = await (await task.onComplete).ref.getDownloadURL();

    return downloadUrl.toString();
  }