0

更新 我认为问题是我从 fetchCredentials() 函数的响应中填充的凭据数组没有被快速填充,因此数组变为空,因此长度不会发生变化,有没有办法等到数组被填充? 此外,如何使第一个 fetch 方法始终运行,但仅在提供的CredentialsArraySize 更改时才呈现 UI。此外,我正在使用平面列表来列出提供的凭据,那么 extraData 道具会帮助我吗?*

我在 useEffect() 和等待中有问题。每次提供的CredentialsArraySize 更改时,我都需要重新渲染代码,我尝试了一切,但似乎没有任何效果。我认为问题出在 fetchCredentials() 函数中的 await 中,因为我理解 await 应该让代码等到此方法完成并返回结果,然后 fetchOfferedCredentials() 应该在数组大小发生变化的地方执行,随后是 console.log() 但事实并非如此,console.log() 在开头打印并且不等待 fetch 和 await 完成。为了使问题更清楚, fetchCredentials() 作为结果返回一个凭据数组,接下来我检查 fetchOfferedCredentials() 函数,如果从第一个函数返回的数组包含任何处于“提供”状态的凭据,如果是这样,我需要重新渲染和打印它们。同样在 fetchOfferedCredentials() 内部,我需要在用户接受报价后删除其中一些凭据,因此我通过检查存储在包含 fetchCredentials() 方法结果的数组中的任何凭据的状态是否再次这样做更改为“已发布”,然后我从提供的数组中删除此提供的凭据,以便其大小再次更改,然后我还需要重新渲染。因此,总而言之,我需要一直运行 fetch,并且每当提供的凭据数组的大小发生变化时,我都需要重新渲染 UI,但我认为 await 中存在问题,有什么帮助吗?下面是代码。先感谢您。同样在 fetchOfferedCredentials() 内部,我需要在用户接受报价后删除其中一些凭据,因此我通过检查存储在包含 fetchCredentials() 方法结果的数组中的任何凭据的状态是否再次这样做更改为“已发布”,然后我从提供的数组中删除此提供的凭据,以便其大小再次更改,然后我还需要重新渲染。因此,总而言之,我需要一直运行 fetch,并且每当提供的凭据数组的大小发生变化时,我都需要重新渲染 UI,但我认为 await 中存在问题,有什么帮助吗?下面是代码。先感谢您。同样在 fetchOfferedCredentials() 内部,我需要在用户接受报价后删除其中一些凭据,因此我通过检查存储在包含 fetchCredentials() 方法结果的数组中的任何凭据的状态是否再次这样做更改为“已发布”,然后我从提供的数组中删除此提供的凭据,以便其大小再次更改,然后我还需要重新渲染。因此,总而言之,我需要一直运行 fetch,并且每当提供的凭据数组的大小发生变化时,我都需要重新渲染 UI,但我认为 await 中存在问题,有什么帮助吗?下面是代码。先感谢您。

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); 

  }
4

1 回答 1

0

因为 fetchCredentials 是一个异步函数,所以它返回一个 Promise。因为您实际上并没有在该函数中返回任何内容,所以 promise 将解析为未定义。如果您希望在 fetchCredentials 完成后调用 fetchOfferedCredentials(),则需要awaitfetchCredentials() 返回的承诺。

你可以试试

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

但是,由于此处此处所述(但未解释)“竞争条件” ,您应该将函数包装在函数内部的另一个异步中:

React.useEffect(() => {
    const fetchAllCredentials = async() => {
    await fetchCredentials();
    fetchOfferedCredentials();
    console.log("This should be printed after the fetch")
  }
  fetchAllCredentials()
  },[offeredCredentialsArraySize]);
于 2020-04-13T13:06:50.257 回答