javascript 你如何根据承诺的结果返回一个布尔值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32405179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:13:05  来源:igfitidea点击:

How do you return a boolean value based on the result of a promise?

javascriptangularjspromiseangular-material

提问by Sean

Working with an AngularJS app (1.4.3), I want a controller to make a call to a method on a service, which should return a boolean value.

使用 AngularJS 应用程序 (1.4.3),我希望控制器调用服务上的方法,该方法应返回布尔值。

Under the hood, the service used to make a call to $window.confirm(), and then just return the result. I am trying to switch the implementation to use Angular Material's $mdDialog.confirm() API, but this returns a promise.

在幕后,该服务过去常常调用 $window.confirm(),然后只返回结果。我正在尝试切换实现以使用 Angular Material 的$mdDialog.confirm() API,但这会返回一个承诺。

The problem I am running into is that there is no way to return true or false directly from my service without changing the code in my controller to expect a promise. The whole purpose of extracting this method into a service was so that the controller could be separated from the implementation details of the call, and I would consider using a promise (ie, a future boolean) vs. a straight boolean to be an implementation detail.

我遇到的问题是,如果不更改控制器中的代码以期待承诺,则无法直接从我的服务返回 true 或 false。将此方法提取到服务中的全部目的是使控制器可以与调用的实现细节分开,我会考虑使用承诺(即未来布尔值)与直接布尔值作为实现细节.

Here is some code to illustrate: In the controller:

下面是一些代码来说明: 在控制器中:

function confirmDeleteDevice() {
    if (notificationService.confirm('Are you sure you want to delete the device?')) {
        deleteDevice();
    }
}

Old function in 'notificationService':

“notificationService”中的旧功能:

function confirm(message) {
    return $window.confirm(message);
}

New function in notificationService that will not work as expected with the controller code above:

NotificationService 中的新函数与上面的控制器代码无法正常工作:

function confirm(message) {
    var confirm = $mdDialog.confirm()
        .title(message)
        .ariaLabel(message)
        .ok('Yes')
        .cancel('No');
    return $mdDialog.show(confirm).then(function() {
        return true;
    }, function() {
        return false;
    });
}

Without changing the controller code to rely on the implementation detail of using a promise, how do I get a boolean value out of my service method? The code above will always execute "deleteDevice()" because the new notificationService.confirm() will return the unresolved promise, which apparently qualifies as a truthy value for the if clause.

在不更改控制器代码以依赖于使用承诺的实现细节的情况下,如何从我的服务方法中获取布尔值?上面的代码将始终执行“deleteDevice()”,因为新的 notificationService.confirm() 将返回未解决的承诺,这显然符合 if 子句的真实值。

I'm definitely no expert on promises, and I understand this isn't exactly how they are expected to be used, but I'd really rather not tie the controller down to using a promise. Is this even possible given the "async" nature of promises?

我绝对不是 Promise 方面的专家,而且我知道这并不是他们期望的使用方式,但我真的不想将控制器与使用 Promise 联系起来。鉴于承诺的“异步”性质,这甚至可能吗?

UPDATE: I definitely looked before I posted and could find nothing, but this just showed upin the "related questions" feed, so I see now my question was a duplicate. The answers there are pretty helpful.

更新:我在发帖之前肯定看过了,什么也没找到,但这只是出现在“相关问题”提要中,所以我现在看到我的问题是重复的。那里的答案很有帮助。

采纳答案by PSL

You will have to make your condition async as well, chaining through the promise.

您还必须使您的条件异步,通过承诺链接。

i.e

IE

notificationService.confirm('...').then(function(confirmation){
     if(confirmation) {
         deleteDevice();
     }
});

and you really would not need to have catch and return falseunless you need to really track the return value since dialog already resolves/rejects the promise based on cancel or Ok, i.e below blocks wont be needed.

并且您真的不需要捕获,return false除非您需要真正跟踪返回值,因为对话框已经基于取消或确定解决/拒绝了承诺,即不需要下面的块。

   .then(function() {
        return true;
    }, function() {
        return false;
    });

So

所以

function confirm(message) {
    var confirm = $mdDialog.confirm()
        .title(message)
        .ariaLabel(message)
        .ok('Yes')
        .cancel('No');

    return $mdDialog.show(confirm);
}

and just:

并且只是:

notificationService.confirm('...').then(deleteDevice);