你如何调用一个未来,然后将该返回值传递到另一个未来运行



我正在尝试用我的Android相机拍照,将该图片上传到Google Firebase Storage,在Storage上获取该图像的可下载URL,并在Firestore上更新用户的照片源。如果我只调用takeImage((,它会获取图像并成功上传到存储。如果我使用虚拟图像 url 调用_uploadImage,它会正确更新提要。但是我无法将 takeImage 的结果作为参数传递给 _uploadImage((。

void takeAndSave() async {
              url = await takeImage();
              _uploadImage(url);

          }

Future<String> takeImage() async {
    // open camera
    var image = await ImagePicker.pickImage(source: ImageSource.camera);
    // save image to temp storage
    final String fileName = "${Random().nextInt(10000)}.jpg";
    Directory directory = await getApplicationDocumentsDirectory(); // AppData folder path
    String appDocPath = directory.path;

    // copy image to path
    File savedImage = await image.copy('$appDocPath/' + fileName);
    // upload file to Firebase Storage
    final StorageReference ref = FirebaseStorage.instance.ref().child(fileName);
    final StorageUploadTask task = ref.putFile(savedImage);
    String downloadURL = await ref.getDownloadURL();
    url = downloadURL;
    //    _image = image;
    return downloadURL;
}

Future<void> _uploadImage(String url) async {
    final FirebaseUser user = await widget.auth.currentUser();
    String uid = user.uid;
    print('uid = ' + uid);
    print(url);
      // upload URL to Firebase Firestore Cloud Storage
      Firestore.instance.runTransaction((Transaction transaction) async {
        DocumentReference _newPhoto = Firestore.instance.collection('users').document(user.uid);
        await _newPhoto.collection('cards').add({"url" : url});
      });
  }

链接未来任务:意味着如果我们有两个未来任务,第二个任务取决于第一个响应的结果,那么我们可以使用" Future.wait() "。在下面的示例中,我创建了两个带有 async 关键字的方法,它们将从服务器获取数据,我想在第一个"fetchPost(("的响应后执行"fetchPostAgain(("方法,然后我可以使用"Future.wait(("。

import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_app/models/Post.dart';
import 'package:http/http.dart' as http;
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }
  FetchFirstPost getFirstPost;
  String myString = "Loading...";
  void _takeImage() {
    Future.wait([fetchPost()]).then((FutureOr) => {
        fetchPostAgain()
    });
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Example'),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              SingleChildScrollView(
                child: Text(myString),
              ),
              RaisedButton(
                    child: Text("Run Future"),
                    onPressed: _takeImage,
                          ),
              ],
          ),
          /*child: CallApiDemo(),*/
        ),
      ),
    );
  }

  Future<Post> fetchPost() async {
    final Completer completer = Completer();
    final response = await http.get('https://jsonplaceholder.typicode.com/posts/1');
    log('data: ' + response .statusCode.toString());
    if (response.statusCode == 200) {
      // If the call to the server was successful, parse the JSON
      setState(() {
        myString = response.body;
      });
      return postFromJson(response.body);
    } else {
      // If that call was not successful, throw an error.
      throw Exception('Failed to load post');
    }
  }
  Future<Post> fetchPostAgain() async{
    final response = await http.get('https://jsonplaceholder.typicode.com/posts/1');
    log('GOT SECOND RESPONSE');
    log('data: ' + response .statusCode.toString());
    if (response.statusCode == 200) {
      setState(() {
        myString = myString + "nnnAGAINnnn" + response.body;
      });
      return postFromJson(response.body);
    } else {
      // If that call was not successful, throw an error.
      throw Exception('Failed to load post');
    }
  }
}

根据您的代码,它应该可以正常工作,但是您的takeImage((方法可能会返回异常。尝试捕获该异常,看看是否有帮助。

以下引用自 https://www.dartlang.org/tutorials/language/futures#async-await

如果 Future-return 函数完成并出现错误,则可能需要捕获该错误。异步函数可以使用 try-catch 处理错误:

Future<String> takeImage() async {
  try {
    // Your code
  } catch (e) {
    // Handle error...
  }
}

最新更新