Asyn c -await не работает должным образом с помощью useEffect () в реактивном режиме. Код не отображается правильно - PullRequest
0 голосов
/ 13 апреля 2020

Обновление Мне кажется, проблема в том, что массив учетных данных, который я заполняю из ответа функции fetchCredentials (), не заполняется быстро, поэтому массив становится пустым, поэтому изменение длины не происходит , есть ли способ ждать, пока массив не будет заполнен? Кроме того, как сделать так, чтобы первый метод выборки выполнялся всегда, но визуализировать пользовательский интерфейс следует только в том случае, если изменен предложилCredentialsArraySize. Также я использую плоский список, чтобы перечислить предлагаемые учетные данные, так поможет ли мне extraData prop? *

У меня проблема в использованииEffect () и ожидании. Мне нужно каждый раз перерисовывать код каждый раз, когда предлагаемый CredentialsArraySize изменяется, я пробовал все, но, похоже, ничего не работает. Я думаю, что проблема заключается в ожидании в функции fetchCredentials (), так как я понимаю, что ожидание должно заставить код ждать, пока этот метод не завершит работу и не вернет результат, а затем fetchOfferedCredentials () должен быть выполнен там, где изменяется размер массива, сопровождаемый console.log (), но это не так, console.log () печатает в начале и не ожидает выборки и ожидания завершения sh. Чтобы сделать проблему более понятной, fetchCredentials () возвращает в результате массив учетных данных, затем я проверяю в функции fetchOfferedCredentials (), содержит ли массив, возвращаемый из первой функции, какие-либо учетные данные в состоянии «предлагаемые», если так, Затем мне нужно перерисовать и распечатать их. Также внутри fetchOfferedCredentials () мне нужно удалить некоторые из этих учетных данных после того, как пользователь примет предложение, поэтому я делаю это снова, проверяя, сохранено ли состояние каких-либо учетных данных, которые хранятся в массиве, содержащем результат метода fetchCredentials () изменив значение на «выдан», я затем удаляю этот предлагаемое значение из предложенного массива, поэтому его размер снова изменяется, а затем мне также потребуется выполнить повторную визуализацию. Таким образом, чтобы подвести итог, мне нужно, чтобы выборка выполнялась все время, и всякий раз, когда размер массива предлагаемыхCredentials изменяется, мне нужно повторно визуализировать пользовательский интерфейс, но я думаю, что есть проблема в ожидании, так что любая помощь? Сильфон это код. Заранее спасибо.

const [credentials, setCredentials] = React.useState([]);
  const [offeredCredentials,setOfferedCredentials] = React.useState([]);
  const [arraySize2, setArraySize2] = React.useState(0); 
  const [connectionDetailsArray, setConnectionDetailsArray] = React.useState(); 
  const [connectionDataArray, setConnectionDataArray] = React.useState([]);
  const [connectionDetailsArraySize, setConnectionDetailsArraySize] = React.useState(0);
  const [count, setCount] = React.useState(0);
  const [offeredCredentialsArraySize,setOfferedCredentialsArraySize] = React.useState(0);
React.useEffect(() => {
    fetchCredentials();
    fetchOfferedCredentials();
    console.log("This should be printed after the fetch")
  },[offeredCredentialsArraySize]);

async function fetchCredentials() {

    const res = await fetch('https://api.streetcred.id/custodian/v1/api/' + walletID + '/credentials', {
       method: 'GET',
       headers: {
        Authorization: 'Bearer ',
        XStreetcredSubscriptionKey: '',
          Accept: 'application/json',
       },
    });
    res.json().then(res => setCredentials(res)).then(setArraySize2(credentials.length));

  }
  async function fetchOfferedCredentials()
  {
    setCount(count+1);
    for (let index = 0; index < arraySize2; index++) 
      {
        if(credentials[index].state=="Offered")
        {
          setOfferedCredentials(addConnectionDetails(offeredCredentials,credentials[index].credentialId, credentials[index]) );
          console.log(offeredCredentials);
        }
      }  

    for (let index = 0; index < offeredCredentials.length; index++)
    {   

     let tempConnectionID= offeredCredentials[index].connectionId;
     const res = await fetch('https://api.streetcred.id/custodian/v1/api/'+walletID+'/connections/'+tempConnectionID, {
       method: 'GET',
       headers: {
        Authorization: 'Bearer L2JBCYw6UaWWQiRZ3U_k6JHeeIkPCiKyu5aR6gxy4P8',
        XStreetcredSubscriptionKey: '4ed313b114eb49abbd155ad36137df51',
          Accept: 'application/json',
       },
    });
    res.json().then(res => setConnectionDetailsArray(res));
    const obj = { id: connectionDetailsArray.connectionId,credentialId:offeredCredentials[index].credentialId, title: connectionDetailsArray.name, image: connectionDetailsArray.imageUrl };    
    setConnectionDataArray(addConnectionDetails(connectionDataArray,obj.id,obj)); 

    }


    for (let index = 0; index < arraySize2; index++) 
    {
      if(credentials[index].state=="Issued")
        {
          for (let index2 = 0; index2 < offeredCredentials.length; index2++) {
              if(offeredCredentials[index2].credentialId == credentials[index].credentialId)
              {
                console.log("here")
                offeredCredentials.splice(index2,1)
                credentials.splice(index,1)
              }
          }

        }
    }
    if(count<50)
    setOfferedCredentialsArraySize(count+1);
    if(currArraySize2!=arraySize2)
    setCount(count+1);
    console.log(offeredCredentials.length); 

  }

1 Ответ

0 голосов
/ 13 апреля 2020

Поскольку fetchCredentials является асинхронной c функцией, она возвращает обещание. Поскольку вы на самом деле ничего не возвращали в этой функции, обещание преобразуется в неопределенное. Если вы хотите, чтобы fetchOfferedCredentials () вызывался после завершения fetchCredentials, вам нужно await это обещание, возвращаемое fetchCredentials ().

Вы можете попробовать

React.useEffect(async () => {
    await fetchCredentials();
    fetchOfferedCredentials();
    console.log("This should be printed after the fetch")
  },[offeredCredentialsArraySize]);

Однако из-за «условий гонки», как указано (но не объяснено) в здесь и здесь , Вы должны обернуть свою функцию в другой асин c внутри функции:

React.useEffect(() => {
    const fetchAllCredentials = async() => {
    await fetchCredentials();
    fetchOfferedCredentials();
    console.log("This should be printed after the fetch")
  }
  fetchAllCredentials()
  },[offeredCredentialsArraySize]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...