探讨:异步与同步的执行差异(结合async await 与 setState)

  async await 与 setState 类似,在主线程执行的时候,遇到异步任务总是先挂载起来,一边执行一边等待主线程上的同步任务执行完毕,等同步任务执行完毕,再发送信号给挂载起来的任务,说你可以进主线程来执行了,此时挂载起来的异步任务中谁先执行完毕谁就先去主线程上执行
  而两者不同的点在于:遇到 async await 的时候,会先返回(把任务挂载),等同步任务执行完毕,再根据挂载任务是否返回值决定是否去主线程执行,然而,async await 在挂载时,跟在其后的语句也会跟着停止执行,只有等 await 返回值,其后的语句才能执行;setState 在挂载时,并不影响其后语句的执行,也就是说当遇到 setState 时,会将 setState 挂载起来,转而去执行其后的同步语句,等 setState 执行完毕,那么再放入主线程执行。如下所示:

import React,{useState, useEffect} from 'react'
import { withRouter } from 'umi';
import { connect } from 'dva';
import decode from 'jwt-decode';
import { Row, Col, Spin, } from 'antd'
import Header from '@/containers/Header'
import SideBar from '@/containers/SideBar' 
import DepRecMedicineContainer from '@/containers/DepRecMedicine'

function Index (props) {
  
  //...

  const [tokenUserInfo, setTokenUserInfo] = useState([])
  const [isReturn, setIsReturn] = useState(false)
  
  const verify = async ()=>{
    const { dispatch } = props
    console.log('1')  // 日志1
    await dispatch({
      type: 'GetData/getToken',
      callback: (data) => {
        setTokenUserInfo(data)
        console.log('2')  // 日志2
        if(data.status === '1'){
          const token = localStorage.getItem('@#@TOKEN')
          const tk = decode(token)
          // console.log('token/index',token)
          if(token){
            try{
              dispatch({
                type: 'GetData/saveData',
                payload: {token: tk}
              })
            }catch{  // 报错
              localStorage.removeItem("@#@TOKEN")
              window.location.href = '/login'
            }
          }
        }else{
          localStorage.removeItem("@#@TOKEN")
          window.location.href = '/login'
        }

      }
    })
    console.log('3')  // 日志3
  }

  useEffect(() => {
    verify()
    console.log('4')  // 日志4
    setIsReturn(true)
    console.log('5')  // 日志5
  },[]) // 指定空数组,只在组件挂载时(刷新)执行一次


  const {location} = props
  console.log('是render内的isReturn',isReturn)  // 打印isReturn
  if(isReturn == true && tokenUserInfo.status == '1'){
    if(location.pathname === '/'){
      return(
        <div style={{height:'100vh', overflow: 'hidden'}}>
          {/* header */}
          <Row>
            <Header />
          </Row>
          {/* body */}
    
          <Row>
              <Col span={3}>
                  <SideBar 
                    // onClickDepRec={onClickDepRec} 
                    // onClickAdmitPatientList={onClickAdmitPatientList}
                    // onClickLeavePatientList={onClickLeavePatientList}
                    // onClickToChangeRightContent={onClickToChangeRightContent}
                  />
              </Col>
    
              <DepRecMedicineContainer />
    
    
              
          </Row>
    
        </div>
      )
    }else{
      return(
        <>
          {props.children}
        </>
      )
    }
  }else{
    return <Spin />
  }
  
 
}
export default connect(({GetData})=>({GetData}))(withRouter(Index))

 

探讨:异步与同步的执行差异(结合async await 与 setState)

 

上一篇:react进阶第三讲——state


下一篇:Warning: setState(...): Can only update a mounted or mounting component. This usually means you call