Синхронные веб-звонки с использованием angular2

У меня есть json с именем, значением и начальным именем. Когда пользователь нажимает кнопку «Отправить», я проверяю, одинаковы ли значение и начальное значение для каждого элемента json. Если значение и начальное значение не совпадают, я вызываю сервисный вызов, используя Rxjs. Если начальное значение и значение одинаковы для всех элементов, должно отображаться сообщение об ошибке, что «данные об ошибке не изменены». Но поскольку вызовы angular2 являются асинхронными, я не могу этого сделать.

Мой json такой-

this.subscriptionList= [{name:"Chat Integration",value:false,initialValue:false},{name:"Dashboard Functionality",value:false,initialValue:false},
{name:"Quarterly Maintenance Window",value:false,initialValue:false},{name:"Remedy Planned Outages",value:false,initialValue:false},
{name:"Schedule Integration",value:false,initialValue:false}];

при нажатии кнопки отправки я вызываю эту функцию-

    submitData()
    {
      var anyChangeDetected: boolean = false;
      for(var i=0;i<this.subscriptionList.length;i++)
      {
        if(this.subscriptionList[i].value != this.subscriptionList[i].initialValue)
        {
          anyChangeDetected = true;
          this.remedyService.submitSubscription(this.subscribeObject).subscribe(
            data =>{

            },
            err=>{

            },
            ()=>{

            });
        }
      }

      if(anyChangeDetected == false)
      {
          alert("Data is not changed");
      }
    }

Теперь проблема заключается в том, что когда я вызываю эту функцию, для веб-вызова происходит асинхронный вызов, и поток напрямую переходит в блок if (anyChangeDetected == false), и каждый раз, когда я получаю это предупреждение. Как я могу этого избежать?


person RAHUL DEEP    schedule 22.09.2016    source источник


Ответы (1)


Это хороший пример использования forkJoin().

Прежде всего создайте временный массив с измененными элементами:

let changed = this.subscriptionList.filter(i => i.value != i.initialValue);

Если changed.length равно 0, вы можете выйти здесь:

if (!changed.length) {
   alert("Data is not changed");
   return; // we can stop..
}

Затем отправьте их и соберите подписки:

let subs = changed.map(i => this.remedyService.submitSubscription(i));

Теперь вы можете использовать forkJoin для получения обратного вызова после выполнения ВСЕХ асинхронных вызовов.

// DO EVERYTHING BEFORE SUBMITTING RESULTS

Observable.forkJoin(subs).subscribe(
   subResults => {
      // all subscribtions done .. 
      let result1 = subResults[0]; // result of first subscribtion
      let resultx = subResults[x]; // result of x'th subscribtion

      // DO EVERYTHING AFTER ALL SUBMITTED

   });
person slaesh    schedule 22.09.2016
comment
Спасибо, mxii, но есть и другие наборы работ, которые мне нужно выполнить до и после вызова службы для всех элементов, таких как загрузка анимации счетчика... - person RAHUL DEEP; 23.09.2016
comment
Есть ли способ выполнять наборы работ до и после всех вызовов службы... чтобы сделать все синхронным, чтобы иметь хороший контроль над программой. - person RAHUL DEEP; 23.09.2016
comment
Взгляните на мои правки, добавил некоторые комментарии. Невозможно сделать его синхронным, потому что веб-вызовы всегда асинхронны! :) - person slaesh; 23.09.2016