等待asyn电话完成 - 为时已晚

时间:2016-07-04 13:09:45

标签: javascript asynchronous dialog wait

我有一个带按钮的对话框。单击该按钮后,将调用异步方法,该方法将返回true或false,具体取决于发布的数据是否有效。 click事件调用下面的方法。 现在,问题是在执行回调函数之前调用closeDialog !! 我怎样才能做到这一点?

由于

#import "ViewController.h"

@interface ViewController ()
{
  NSMutableArray *arrProductSelection,*arrProductSelectDeSelectCheckMark;
  NSArray *arrayFetchFromDefaults;
  NSInteger lastSelectedIndex;
}

@end

@implementation ViewController

@synthesize tableViewCheckMarkSelectionUpdate;

- (void)viewDidLoad 
{
  [super viewDidLoad];
  // Do any additional setup after loading the view from its nib.
  arrProductSelection = [[NSMutableArray alloc]initWithObjects:@"iPhone",@"iPad",@"iPod",@"iTV",@"iWatch",@"iMac",nil];
}

- (void)didReceiveMemoryWarning {
 [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

-(void)viewWillAppear:(BOOL)animated
{
   [NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
   arrayFetchFromDefaults = [userDefaults objectForKey:@"selectedcheckmark"];
   arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]initWithArray:arrayFetchFromDefaults];
   if(arrProductSelectDeSelectCheckMark.count == 0)
   {
      arrProductSelectDeSelectCheckMark = [[NSMutableArray alloc]init];
      for(int j=0;j<[arrProductSelection count];j++)
      {
        [arrProductSelectDeSelectCheckMark addObject:@"deselected"];
      }
   }
   [tableViewCheckMarkSelectionUpdate reloadData];

}


#pragma mark - UITableViewDataSource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
  return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  return arrProductSelection.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   NSString *strCell = @"cell";
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
   if(cell==nil)
   {
     cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
   }

   // lastSelectedIndex =  [[NSUserDefaults standardUserDefaults] integerForKey:@"selectedRow"]; - Getting Last selected index row

   if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:@"deselected"])
     cell.accessoryType = UITableViewCellAccessoryNone;

   else
     cell.accessoryType = UITableViewCellAccessoryCheckmark;

   //    if (indexPath.row == lastSelectedIndex)
   //        cell.accessoryType = UITableViewCellAccessoryCheckmark;

   cell.textLabel.text = [arrProductSelection objectAtIndex:indexPath.row];
   return cell;
 }


#pragma mark - UITableViewDelegate Methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   // [[NSUserDefaults standardUserDefaults] setInteger:indexPath.row forKey:@"selectedRow"];  //This is for Last Selected IndexPath Row

   UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
   @try
   {
     CGPoint touchPoint = [cell convertPoint:CGPointZero toView:tableViewCheckMarkSelectionUpdate];
     NSIndexPath *indexPath = [tableViewCheckMarkSelectionUpdate indexPathForRowAtPoint:touchPoint];
     NSLog(@"%@",arrProductSelectDeSelectCheckMark);
     if([arrProductSelectDeSelectCheckMark count]==0)
     {
        for(int i=0; i<[arrProductSelection count]; i++)
        {
            [arrProductSelectDeSelectCheckMark addObject:@"deselected"];
        }
     }
     if([[arrProductSelectDeSelectCheckMark objectAtIndex:indexPath.row] isEqualToString:@"deselected"])
     {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:@"selected"];
     }
     else
     {
        cell.accessoryType = UITableViewCellAccessoryNone;
        [arrProductSelectDeSelectCheckMark replaceObjectAtIndex:indexPath.row withObject:@"deselected"];
     }

     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     [defaults setObject:arrProductSelectDeSelectCheckMark forKey:@"selectedcheckmark"];
     [defaults synchronize];
  }
  @catch (NSException *exception) {
    NSLog(@"The exception is-%@",exception);
  }
}

- (IBAction)actionGoPrevious:(id)sender
{
   [self.navigationController popToRootViewControllerAnimated:YES];
}
@end

4 个答案:

答案 0 :(得分:1)

你应该看看使用诺言。 JQuery Ajax调用本机返回一个Promise。

EG:

$.ajax(ajaxObj).success(function(resp) { console.log('I have completed');});

将对话框放在通话的成功或失败部分。

答案 1 :(得分:1)

根据您的代码段,它应如下所示:

close: function (srcCmd) {
   var closeResult = true;
   asyncThing(function(result) {
      if (result)
         this.closeDialog();

   }); 
},

在您的版本中此代码

if (closeResult !== false) {
    this.closeDialog();
}
在调用asyncThing的回调之前调用

。这就是调用对话closeDialog的原因

答案 2 :(得分:0)

当异步调用完成时(无论何时可能),调用带有asyncThing的函数。所以这不会逐行解释。

如果对回调函数有疑问,请移动后者,它会没问题。

close: function (srcCmd) {
   var closeResult = true;
   asyncThing(function(result) {
       if (result)
           closeResult = true;
       else
           closeResult = false;
    if (closeResult !== false) {
       this.closeDialog();
    }
  });
},

答案 3 :(得分:0)

这是因为此代码的异步部分是回调函数。并且您在同步部分中调用close对话框,该部分在发送请求后立即运行。 只需将调用移至回调。

如上所述,您还需要在回调函数中处理this,因为js在运行时确定this。所以它并不总是对你的对象的引用。

一种方法是将this缓存在回调之外的另一个变量中。

close: function (srcCmd) {
   var self = this;
   var closeResult = true;
   asyncThing(function(result) {
      if (result)
         closeResult = true;
         self.closeDialog();
      else
         closeResult = false;
   }); 
},

另一种方法是使用其中一种绑定方法(.bind,.call,.apply):

close: function (srcCmd) {
   var closeResult = true;
   asyncThing(function(result) {
      if (result)
         closeResult = true;
         this.closeDialog();
      else
         closeResult = false;
   }.bind(this)); 
},

还有用于处理异步的Promise模式。但是使用起来比较困难。