如何使用 componentDidMount() 在 render() 中创建异步 return 承诺链?

How to make an asynchronous return a promise chain within render() with componentDidMount()?

我的 return 在我的渲染函数中有一个按钮调用一个函数来启动一个承诺链,结果更新一个状态变量。但是,该值未通过。

我在 componentDidMount() 上尝试了一些尝试,但没有成功

这是我的渲染函数中的按钮

<button onClick={this.addIPFSItem} className="btn btn-info btn-sm m-1">NewFile</button>

这会调用以下函数

addIPFSItem(){

var searchAddress = "0x9Cf0dc46F259542A966032c01DD30B8D1c310e05";

const contract = require('truffle-contract')
const simpleStorage = contract(SimpleStorageContract)
simpleStorage.setProvider(this.state.web3.currentProvider)


this.state.web3.eth.getAccounts((error, accounts) => {
  simpleStorage.deployed().then((instance) => {
    this.simpleStorageInstance = instance

    return this.simpleStorageInstance.getLength(searchAddress);
  }).then((accountLength) => {

    var items = []
    const ipfsPrefix = "https://ipfs.io/ipfs/";

    var i;
    for (i = 0; i < accountLength; i++) {
      var currHash = this.simpleStorageInstance.getBook(searchAddress, i, 
  {from: searchAddress});

      var currURL = ipfsPrefix + this.currHash;

      //Here I am printing the counter values, and it prints the correct 
      //amount
      console.log('itemhash ', i)
      items.push(currHash)
    }
    //I do not get the value of items[1] in the console, but an undefined
    //promise
    console.log('address URL ', items[1])

    //the state of ipfsHash is not updated correctly
    return this.setState({ipfsHash: items[1]});
  })
 })
}

本质上,我正在执行承诺链(通过连接到 web3)并检索数据。我认为根本问题是我在 render() 中调用异步函数。我不确定如何使用 componentDidMount()

解决这个问题

console.log('address URL ', items[1]) 应该给出类似 address URL 0x9Cf0dc46F259542A966032c01DD30B8D1c310e05 的内容。但是,我得到的是 address URL Promise{<pending>}

你的this.simpleStorageInstance.getBook是一个promise,也就是说它是异步执行的。

要获得结果,您必须使用 .then 或新语法 async/await。使用以下函数,您的 items 数组将填充正确的数据:

You will have to put the async keyword before your parent function name if you choose this solution

for (i = 0; i < accountLength; i++) {
    items.push(await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))
}

更短的语法意味着使用您的原始帐户数组 map 而不是使用它的长度 :

const items = myAccounts.map(async () => await this.simpleStorageInstance.getBook(searchAddress, i, { from: searchAddress }))