Как сделать массив доступным для разных функций в Javascript?

Я использую React Table для извлечения данных из API и заполнения их в таблице. Я делаю вызов API и получаю данные. Когда у меня есть данные, я извлекаю поле, содержащее идентификаторы электронной почты, а затем создаю массив (emailList). Теперь я хочу использовать данные в emailList как часть тела в вызове POST API впоследствии. Таким образом, в приведенном ниже коде параметр получателей при вызове POST должен содержать данные emailList. EmailList объявлен как пустой массив глобально в методе рендеринга. С моей текущей настройкой я получаю неопределенную ошибку из-за проблем с областью действия. Как сделать значение доступным при вызове POST? Я просмотрел несколько ответов StackOverflow и попытался, но не получил результата.

    columns: [
    {
filterable: false,
Header: 'Action',
accessor: 'action',
Cell: (e) => (
  <button
      onClick={() => {
        axios.get(URL, {
          headers: {
            'content-type': 'application/json',
            'Name' : user.Name,
          },
          responseType: 'json',
        })
        .then((response) => {
          let responseData = response.data.data;
          function getEmailList(input, email) {
            var output = [];
            for (var i=0;i<input.length; ++i)
              output.push(input[i][email]);
            return output;
          }
          emailList = getEmailList(responseData, "email");

          function fetchEmail() {
            this.emailList = getEmailList(responseData, "email");
          }  

        });

        //console.log(new fetchEmail().emailList);
        //Unable to get the value of emailList here
        axios({
          method: 'post',
          url: URL2,
          headers: {
            'content-type': 'application/json',
            'Name' : user.Name,
          },
          data: {
            "topic": "product",
            "message": {
               "sender": "[email protected]",
               //For illustration I have hardcoded the email arrays for recipients
               "recipients": ["[email protected]", "[email protected]"],
              "data": {
                        "text": "refresh"
              },
           "attachment": null,
           "type": "",
            },
          },
        })

person SeaWarrior404    schedule 18.09.2017    source источник


Ответы (1)


Я думаю, что это скорее проблема гонки (например, вы пытаетесь опубликовать сообщение до того, как электронные письма поступят в браузер), поэтому вам нужно изменить свой код, чтобы сообщение ожидало получения. Это можно легко сделать с помощью промисов:

 {
   //a cache
   let promise;

   //a promising getter:
   function getEmails (){
     //if cached return
     if( promise ) return promise;
     //else await the request
     return promise = axios.get(URL,{/*options*/}).then( response => response.data.data.map(obj => obj.email));
   }
 }

Итак, теперь мы можем сделать:

 getEmails().then( console.log);
 getEmails().then( console.log);

Оба вызова вернут одно и то же обещание, поэтому есть только один запрос, но мы можем вызывать его несколько раз. Например, мы можем вызвать его перед выполнением POST:

 getEmails().then( emails => {
  axios({
   //...
   data:{
    message:{
      recipients: emails
    }
  }
 });
});
person Jonas Wilms    schedule 18.09.2017