Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS和服务内部的异步函数_Javascript_Angularjs_Cordova - Fatal编程技术网

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: