Обещание, асинхронное ожидание

setDeviceTimeout = id => timeout => {
    const {onSetDevices, devices} = this.props;

    var newDeviceList = devices.map(device => {
        if (device.id === id) {
            var newDevice = {
                //...device,
                timeout: timeout
            };
            deviceTable.oncePostDevice(newDevice).then( data => {
                return newDevice = data
            });
        }
        return device;
    });

    onSetDevices(newDeviceList);
}

Итак, проблема, с которой я столкнулся, заключается в том, что onSetDevices(newDeviceList) вызывается до завершения работы devices.map(). Это связано с тем, что devices.map() обращается к серверу oncePostDevice(newDevice), затем возвращает данные, сохраняет их в переменной newDevice и помещает их в массив newDeviceList.

Поскольку это происходит, onSetDevices не включает newDevice в массив объектов newDeviceList, и когда я устанавливаю свое состояние редукции с помощью onSetDevices, ничего не изменилось.

Мне интересно, как я могу превратить это в асинхронный, Ждите или использовать только обещать, чтобы завершить задачу, заставляющую onSetDevices ждать завершения devices.map().

Также вот код для oncePostDevice:

export const oncePostDevice = (device) => new Promise(function(resolve, reject) {

    fetch('https://url/devices/'+device.id, {
        method: 'PUT',
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify(device)
    })
    .then(response => response.json())
    .then(
        data => {return resolve(data)},
        error => {return reject(error)}
    )
    .catch(err => console.error(this.props.url, err.toString()));
});

Как видите, у меня уже есть обещать, работающий и возвращающий данные впоследствии.

Мне просто нужно знать, как завершить работу моей функции внутреннего сопоставления setDeviceTimeout, прежде чем я нажму на onSetDevices.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
128
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот как это можно сделать (пояснения в коде):

// make the function async
setDeviceTimeout = id => async timeout => {
  const {onSetDevices, devices} = this.props;

  // make a list of promises, not of devices
  // note: mapping a value via an async function will create promises
  const newDeviceListPromises = devices.map(async device => {
    if (device.id === id) {
      const newDevice = {
        ...device,
        timeout: timeout
      };
      return await deviceTable.oncePostDevice(newDevice);
    }
    return device;
  });

  // wait for all promises to finish and what they return will be the devices
  const newDeviceList = await Promise.all(newDeviceListPromises);

  onSetDevices(newDeviceList);
};

Идеально!!! Спасибо, сэр! Это сработало как шарм, я действительно не могу вас отблагодарить, я ломал себе голову, пытаясь решить эту проблему.

Saccoon 19.03.2018 16:28

Другие вопросы по теме