Значения Promise помещаются в массив в неправильном порядке - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь поместить значения sh в массив, однако значения выводятся в неправильном порядке.

//Returns ongoing stream of the decibels in the room 
async getNoise() {
  let subscription = this.dbMeter.start().subscribe(data => {
    this.noiseDb = data;
    return data;
  });
}​ //Returns your current location 
getPosition() {
  return new Promise((res, rej) => {
    navigator.geolocation.getCurrentPosition(res, rej);
  });
}

async startTimer() {
  this.interval = setInterval(async() => {

    interface pos {
      coords ? : any,
    }

    var position: pos = await this.getPosition(); // wait for getPosition to complete

    this.getNoise();

    objects.push({
      lat: position.coords.latitude,
      long: position.coords.longitude,
      noise: this.noiseDb
    });
  }, 500);

}

Это прекрасно работает при 2-секундной задержке, однако при наличии задержка в одну секунду или полсекунды, как показано выше, значения помещаются в массив в неправильном порядке, и одно и то же значение используется для нескольких записей. Например,

[{"lat":55.7558,"long":4.4784,"noise":45.58059,"time":"1.01"},
{"lat":55.7558,"long":4.4784,"noise":45.58059,"time":"2.01"}, 
{"lat":55.7558,"long":4.4784,"noise":40.197384,"time":"4.01"}, 
{"lat":55.7558,"long":4.4784,"noise":40.197384,"time":"3.01"}]

Я считаю, что мне нужно использовать Promise.all (), но я не уверен, как мне это реализовать. Кто-нибудь может мне помочь?

1 Ответ

0 голосов
/ 08 января 2020

Это потому, что вызовы asyn c не ожидают завершения предыдущего вызова перед выполнением. Вот почему они асин c. Они обычно используются для операций ввода-вывода, которые требуют времени для выполнения. Вместо ожидания 0,5-1 секунды каждый раз, когда метод asyn c не будет блокировать поток, поэтому будут выполняться другие вызовы во время выполнения функции asyn c (например, во время загрузки файла или получения геолокации браузер может обновить пользовательский интерфейс). плавно).

В вашем случае вы вызываете функцию asyn c каждые 500 мс. Как я уже говорил, функции asyn c не ждут завершения предыдущей. Так что, если второй вызов выполнен до первого, ваш порядок в списке будет неправильным. Чтобы решить эту проблему, я предлагаю написать свой код, как показано ниже:

let running = true;

startTimer() {
  if (!running) return;

  setTimeout(async() => {
    interface pos {
      coords ? : any,
    }

    var position: pos = await this.getPosition(); // wait for getPosition to complete

    this.getNoise();

    objects.push({
      lat: position.coords.latitude,
      long: position.coords.longitude,
      noise: this.noiseDb
    });

    startTimer();
  }, 500);
}

startTimer();

Чтобы запустить таймер, установите running = true, затем позвоните startTimer(). Чтобы остановить таймер, просто установите running = false.

. Я использовал setTimeout вместо setInterval, потому что я получу следующую геолокацию только после того, как закончу выбор текущей.

...