为什么调用 API 的函数返回空值或 null 值?
(免责声明:当人们通过 facebook、firebase 等请求使用异步操作时,会出现很多关于数据为空/不正确的问题.我提出这个问题的目的是提供一个简单的为所有开始在 android 中使用异步操作的人回答这个问题)
我正在尝试从我的一项操作中获取数据,当我使用断点或日志对其进行调试时,值在那里,但是当我运行它时,它们始终为空,我该如何解决这个问题?
I'm trying to get data from one of my operations, when I debug it using breakpoints or logs, the values are there, but when I run it they are always null, how can I solve this ?
Firebase
firebaseFirestore.collection("some collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
//I want to return these values I receive here?
})
脸书
GraphRequest request = GraphRequest.newGraphPathRequest(
accessToken,
"some path",
new GraphRequest.Callback() {
@Override
public void onCompleted(GraphResponse response) {
//I want to return these values I receive here?
}
});
request.executeAsync();
等等
推荐答案
什么是同步/异步操作?
好吧,同步等到任务完成.您的代码执行自上而下";在这种情况下.
Well, Synchronous waits until the task has completed. Your code executes "top-down" in this situation.
异步在后台完成一项任务,并在完成时通知您.
Asynchronous completes a task in the background and can notify you when it is complete.
如果您想通过方法/函数从异步操作返回值,您可以在方法/函数中定义自己的回调,以便在这些操作返回时使用这些值.
If you want to return the values from an async operation through a method/function, you can define your own callbacks in your method/function to use these values as they are returned from these operations.
Java 的方法如下
首先定义一个接口:
interface Callback {
void myResponseCallback(YourReturnType result);//whatever your return type is: string, integer, etc.
}
接下来,将您的方法签名更改为:
next, change your method signature to be like this :
public void foo(final Callback callback) { // make your method, which was previously returning something, return void, and add in the new callback interface.
接下来,无论您以前想在哪里使用这些值,请添加以下行:
next up, wherever you previously wanted to use those values, add this line :
callback.myResponseCallback(yourResponseObject);
举个例子:
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
// create your object you want to return here
String bar = document.get("something").toString();
callback.myResponseCallback(bar);
})
现在,您之前调用了名为 foo
的方法:
now, where you were previously calling your method called foo
:
foo(new Callback() {
@Override
public void myResponseCallback(YourReturnType result) {
//here, this result parameter that comes through is your api call result to use, so use this result right here to do any operation you previously wanted to do.
}
});
}
您如何为 Kotlin 做到这一点?(作为一个基本示例,您只关心单个结果)
How do you do this for Kotlin ? (as a basic example where you only care for a single result)
首先将您的方法签名更改为以下内容:
start off by changing your method signature to something like this:
fun foo(callback:(YourReturnType) -> Unit) {
.....
然后,在您的异步操作结果中:
then, inside your asynchronous operation's result :
firestore.collection("something")
.document("document").get()
.addOnSuccessListener {
val bar = it.get("something").toString()
callback(bar)
}
然后,您之前会调用名为 foo
的方法,现在您可以这样做:
then, where you would have previously called your method called foo
, you now do this :
foo() { result->
// here, this result parameter that comes through is
// whatever you passed to the callback in the code aboce,
// so use this result right here to do any operation
// you previously wanted to do.
}
// Be aware that code outside the callback here will run
// BEFORE the code above, and cannot rely on any data that may
// be set inside the callback.
如果你的 foo
方法之前接受了参数:
if your foo
method previously took in parameters :
fun foo(value:SomeType, callback:(YourType) -> Unit)
您只需将其更改为:
foo(yourValueHere) { result ->
// here, this result parameter that comes through is
// whatever you passed to the callback in the code aboce,
// so use this result right here to do any operation
// you previously wanted to do.
}
这些解决方案展示了如何创建一个方法/函数来从您通过使用回调执行的异步操作中返回值.
these solutions show how you can create a method/function to return values from async operations you've performed through the use of callbacks.
但是,重要的是要了解,如果您对为这些创建方法/函数不感兴趣:
However, it is important to understand that, should you not be interested in creating a method/function for these:
@Override
public void onSuccess(SomeApiObjectType someApiResult) {
// here, this `onSuccess` callback provided by the api
// already has the data you're looking for (in this example,
// that data would be `someApiResult`).
// you can simply add all your relevant code which would
// be using this result inside this block here, this will
// include any manipulation of data, populating adapters, etc.
// this is the only place where you will have access to the
// data returned by the api call, assuming your api follows
// this pattern
})
相关文章