英文:
Updating AtomicBoolean from within lambda expression
问题
I'm passing a lambda expression as an argument to a method, and I want to modify a variable that is defined outside of the lambda expression.
我正在将一个Lambda表达式作为参数传递给一个方法,并且我想修改在Lambda表达式之外定义的变量。
I've tried a few things. Currently, I have an AtomicBoolean
called success
. Within the lambda expression, I'm calling success.set(true)
. However, when I log the value of the success
variable, it's still false
and doesn't seem to be updating.
我尝试了一些方法。目前,我有一个名为success
的AtomicBoolean
。在Lambda表达式内部,我调用了success.set(true)
。然而,当我记录success
变量的值时,它仍然是false
,似乎没有更新。
Basically, I'm calling a function with a void return type and need to know if the function was successful.
基本上,我正在调用一个返回void类型的函数,需要知道函数是否成功。
What am I doing wrong?
我做错了什么?
Here's the code:
这是代码:
public void createUser(String email, String password) {
AtomicBoolean success = new AtomicBoolean(false);
Amplify.Auth.signUp(
email,
password,
AuthSignUpOptions.builder()
.userAttribute(AuthUserAttributeKey.email(), email)
.build(),
result -> success.set(true),
error -> Log.e("AuthQuickStart", "Sign up failed", error)
);
Log.d("success", String.valueOf(success.get()));
}
英文:
I'm passing a lambda expression as an argument to a method, and I want to modify a variable that is defined outside of the lambda expression.
I've tried a few things. Currently, I have an AtomicBoolean
called success
. Within the lambda expression, I'm calling success.set(true)
. However, when I log the value of the success
variable, it's still false
and doesn't seem to be updating.
Basically, I'm calling a function with a void return type and need to know if the function was successful.
What am I doing wrong?
Here's the code:
public void createUser(String email, String password) {
AtomicBoolean success = new AtomicBoolean(false);
Amplify.Auth.signUp(
email,
password,
AuthSignUpOptions.builder()
.userAttribute(AuthUserAttributeKey.email(), email)
.build(),
result -> success.set(true),
error -> Log.e("AuthQuickStart", "Sign up failed", error)
);
Log.d("success", String.valueOf(success.get()));
}
答案1
得分: 2
如果signUp
方法是阻塞的(即在注册完成后返回),则您的代码应该按预期工作。因此,我怀疑它是异步的。
在这种情况下,除了使用布尔值之外,您还可以使用CountDownLatch
来等待异步方法完成:
AtomicBoolean success = new AtomicBoolean(false);
CountDownLatch done = new CountDownLatch(1);
Amplify.Auth.signUp(
email,
password,
AuthSignUpOptions.builder().userAttribute(AuthUserAttributeKey.email(), email).build(),
result -> { success.set(true); done.countDown(); },
error -> { Log.e("AuthQuickStart", "Sign up failed", error); done.countDown(); }
);
done.await(); //您可能想要在此处添加超时
Log.d("success", String.valueOf(success.get()));
英文:
If the signUp
method is blocking (i.e. it returns once the signup is finished), your code should work as expected. So I suspect it is asynchronous.
In that case, on top of using a boolean, you could also use a CountDownLatch
to wait until the async method completes:
AtomicBoolean success = new AtomicBoolean(false);
CountDownLatch done = new CountDownLatch(1);
Amplify.Auth.signUp(
email,
password,
AuthSignUpOptions.builder().userAttribute(AuthUserAttributeKey.email(), email).build(),
result -> { success.set(true); done.countDown(); },
error -> { Log.e("AuthQuickStart", "Sign up failed", error); done.countDown(); }
);
done.await(); //you may want to add a timeout here
Log.d("success", String.valueOf(success.get()));
答案2
得分: 1
An AtomicBoolean
variable (success
) is used correctly. Most probably,
Log.d("success", String.valueOf(success.get()));
is called before
result -> success.set(true)
because of asynchronous execution of callback. Alternatively result callback is not called at all.
You can test it by changing callback body to:
result -> {
Log.d("callback test", "callback start");
result -> success.set(true);
Log.d("callback test", "callback end");
}
If "callback test" doesn't appear in the logs then callback is not called.
If "callback test" appears after "success" then callback body is called after Log.d("success", String.valueOf(success.get())); due to asynchronous execution.
英文:
An AtomicBoolean
variable (success
) is used correctly. Most probably,
Log.d("success", String.valueOf(success.get()));
is called before
result -> success.set(true)
because of asynchronous execution of callback. Alternatively result callback is not called at all.
You can test it by changing callback body to:
result -> {
Log.d("callback test", "callback start");
result -> success.set(true);
Log.d("callback test", "callback end");
}
If "callback test"
doesn't appear in the logs then callback is not called.<br>
If "callback test"
appear after "success"
then callback body is called after Log.d("success", String.valueOf(success.get()));
due to asynchronous execution.
答案3
得分: 1
@assylias 和 @jakub-bialy 的答案是完全有效的。但是,它们都没有考虑到 error
回调函数。另外,直接使用 CountDownLatch
有点底层。
Amplify 提供了一个 rxbindings
模块,可以帮助简化异步编程。
在你的情况下,你可以使用 signUp(...)
方法的 Rx 版本,像这样:
// 将初始化更改为:
RxAmplify.addPlugin(new AWSCognitoAuthPlugin())
RxAmplify.configure(getApplicationContext())
// 阻塞方式进行注册:
AuthSignUpOptions options = AuthSignUpOptions.builder()
.userAttribute(AuthUserAttributeKey.email(), email)
.build();
AuthSignUpResult result =
RxAmplify.Auth.signUp(email, password, options)
.timeout(10, TimeUnit.SECONDS)
.blockingGet();
在这种情况下,signUp(...)
调用将以阻塞方式在调用它的线程中抛出 error
。而在其他答案中,这个 error
被忽略了。
英文:
@assylias's and @jakub-bialy's answers are totally valid. However, neither considers the error
callback. Additionally, using a CountDownLatch
directly is a little low-level.
Amplify provides an rxbindings
module, which can help simplify asynchronous programming.
In your case, you could use the Rx version of the signUp(...)
method, like so:
// Change your initialization to:
RxAmplify.addPlugin(new AWSCognitoAuthPlugin())
RxAmplify.configure(getApplicationContext())
// Sign-up, in a blocking way:
AuthSignUpOptions options = AuthSignUpOptions.builder()
.userAttribute(AuthUserAttributeKey.email(), email)
.build();
AuthSignUpResult result =
RxAmplify.Auth.signUp(email, password, options)
.timeout(10, TimeUnit.SECONDS)
.blockingGet();
The signUp(...)
call in this case will throw the error
in a blocking way, in the thread that makes the call. In the other answers, this error
is ignored.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论