Javascript AngularJS和服务内部的异步函数
我在异步函数中遇到了这个问题。关键是“执行”并不是在等待Javascript AngularJS和服务内部的异步函数,javascript,angularjs,cordova,Javascript,Angularjs,Cordova,我在异步函数中遇到了这个问题。关键是“执行”并不是在等待NotificationService.confirm回调的返回 我的意思是,这显示了一个PhoneGap警报,但它并不等待用户按下哪个按钮。因此,您可以在控制台输出中看到未定义的值,而不是false/true/3值 [编辑] 这是Maxim Shoutin提出的代码,但尚未生效: NotificationController.js angular.module('app').controller("NotificationControll
NotificationService.confirm
回调的返回
我的意思是,这显示了一个PhoneGap警报,但它并不等待用户按下哪个按钮。因此,您可以在控制台输出中看到未定义的值,而不是false/true/3值
[编辑]
这是Maxim Shoutin提出的代码,但尚未生效:
NotificationController.js
angular.module('app').controller("NotificationController", function($rootScope) {
$rootScope.cancel_button = function() {
var confirm = NotificationService.confirm("Do you want to confirm?", 'Yes!');
confirm.then(function(result) {
console.log('Confirm: ' + result);
if(confirm) $location.path('/menu');
}, function(result) {
console.log('No data returned');
})
}
/* Additional controller code... */
}
angular.module('app').factory("NotificationService", function() {
// Callback function
var onConfirm = function(button) {
console.log('Callback function called!!!');
if(button == 1) return false;
else if(button == 2) return true;
else if(button == 3) return 3;
else return false; // dismissed without press button
};
return {
confirm : function(alert_msg, title, buttonsArray) {
var deferred = $q.defer();
if(buttonsArray == null) {
buttonsArray = ['Cancel', 'OK'];
}
var data = navigator.notification.confirm(
alert_msg, // message
onConfirm, // callback
title, // title
buttonsArray // buttonsArray
);
deferred.resolve(data);
return deferred.promise;
}
}
}
NotificationService.js
angular.module('app').controller("NotificationController", function($rootScope) {
$rootScope.cancel_button = function() {
var confirm = NotificationService.confirm("Do you want to confirm?", 'Yes!');
confirm.then(function(result) {
console.log('Confirm: ' + result);
if(confirm) $location.path('/menu');
}, function(result) {
console.log('No data returned');
})
}
/* Additional controller code... */
}
angular.module('app').factory("NotificationService", function() {
// Callback function
var onConfirm = function(button) {
console.log('Callback function called!!!');
if(button == 1) return false;
else if(button == 2) return true;
else if(button == 3) return 3;
else return false; // dismissed without press button
};
return {
confirm : function(alert_msg, title, buttonsArray) {
var deferred = $q.defer();
if(buttonsArray == null) {
buttonsArray = ['Cancel', 'OK'];
}
var data = navigator.notification.confirm(
alert_msg, // message
onConfirm, // callback
title, // title
buttonsArray // buttonsArray
);
deferred.resolve(data);
return deferred.promise;
}
}
}
控制台输出
>确认:未定义(用户按下按钮之前)
调用回调函数代码>(用户按下按钮后)问题是通知服务。确认(“您想确认吗?”,“是!”)代码>返回承诺(即异步)
所以应该是这样的:
var confirm = NotificationService.confirm("Do you want to confirm?", 'Yes!');
// now confirm is a promise
confirm.then(function (result) {
console.log('Confirm: ' + confirm);
if(confirm) $location.path('/round/actual');
}, function (result) {
alert("Error: No data returned");
})
仅在演示中,我们可以使用$timeout
模拟异步调用:
app.factory('NotificationService', function($q,$timeout) {
// Callback function
var onConfirm = function(button) {
var state;
console.log('Callback function called!!!');
if(button == 1) state = 'working!';
else state = false; // dismissed without press button
return state;
};
var factory = {
confirm : function(alert_msg, title, buttonsArray) {
var deferred = $q.defer();
$timeout(function () {
var state = onConfirm(1); // simulate call callback after 3 sec
deferred.resolve(state);
}, 3000);
return deferred.promise;
}
}
return factory;
});
演示
在您的情况下,因为navigator.notification.confirm
使用回调,所以您可以尝试从回调返回resolve。问题是您在数据实际返回之前解决了承诺。您需要为您的onConfirm
函数提供访问通知服务的权限。确认正在返回,并且只在其中调用解析。$q
通过让方法引用可能还不存在的答案来工作,并让他们注册回调,以便在应答完成时运行。这意味着,如果您在与resolve()
相同的代码块中调用defer()
,那么您并不是在异步使用承诺,因为您在承诺发出后立即对其进行解析
您需要删除延迟。从确认功能块解析(数据)
,并将其放在回调函数中resolve()
应该始终进入某种回调函数,因为回调函数是等待异步事件的方式。如果您可以在getter中解析承诺,那么它就不是真正的异步的
然后,将onConfirm
方法更改为如下所示:
var onConfirm = function(button) {
console.log('Callback function called!!!');
var result= false;
// if(button == 1) default case
if(button == 2) { result = true; }
else if(button == 3) { result = 3; }
// else default case
deferred.resolve(result);
};
现在,我们只有在Notification回调中才能解析承诺,这意味着用户已经做出了选择,我们根据用户的决定来解析承诺
最后,您会注意到,如果onConfirm
不在您的服务范围内,它将无法访问需要解析的deferred
对象。将onConfirm
移动到confirm
函数中,这样它就可以对该变量进行闭包访问。几乎完成了,但尚未完成。我的意思是,如果我执行一个console.log(result),输出是未定义的,因为直到用户按下按钮,执行才被“暂停”。我用codeHmm更新了ask,在Plunker中,数据
是单一方法,但它应该是通过异步方式获得的类似数组或模型的值。我无法添加navigator.notification,因为它来自Cordova.js,在这里不起作用。因此,我让它发挥作用。您可以使用任何简单的测试进行修改。谢谢你抽出时间!查看我发布的编辑,我在phonegap的文档中看到,navigator.notification
仅使用回调示例plunker: