列举三类

第一类:很多个异步,依次执行,要有顺序

  • 方法一 使用加载事件特性(img的src变化,load事件执行)
/**
 * 图片加载
 */
function getImage(num){
    let img = new Image()
    img.src = `./image/${num}.png`
    img.num = num
    img.arr = []
    img.addEventListener('load',loadHandle)
}

function loadHandle(e){
    let cloneImg = e.currentTarget.cloneNode()
    this.arr.push(cloneImg)
    this.num++
    if(num > 59) return this.arr
    that.src = `./image/${this.num}.png`
}
  • 方法二 使用Promise
/**
 * 图片加载
 */
function getImage2(num){
    return new Promise((resolve,reject)=>{
        let img = new Image()
        img.src = `./image/${num}.png`
        img.onload = function(){
            resolve(img)
        }
    })
}

function main(total){
    let arr = []
    for(let i = 0; i < total; i++){
        let img = getImage2(i)
        arr.push(img)
    }
    if(arr.length === 56){
        Promise.all(arr).then(list=>{
            console.log(list)
        })
    }
}

  • 方法三 使用Promise和async
/**
 * 图片加载
 */
function getImage1(num){
    return new Promise((resolve,reject)=>{
        let img = new Image()
        img.src = `./image/${num}.png`
        img.onload = function(){
            resolve(img)
        }
    })
}

async function main(total){
    let arr = []
    for(let i = 0; i < total; i++){
        let img = await getImage(i)
        arr.push(img)
    }
}
/**
 * 音频加载
 */
function loadFile(item){
        return new Promise((resolve,reject)=>{
            let { name, url, fileId, size } = item
            let temp = new Audio(url)
            temp.onloadedmetadata = function(){
                resolve({
                    audioName: name.slice(0,40),
                    audioUrl: url,
                    fileId: fileId,
                    fileSize: size,
                    duration: temp.duration 
                })
            }
            temp.onerror = function(){        // 没有监听error事件,加载失败后,会卡住不继续执行
              resolve({
                audioName: name.slice(0,40),
                audioUrl: url,
                fileId: fileId,
                fileSize: size,
                duration: temp.duration || 0
              })
            }
        })
    }

    //上传腾讯云成功的回调
    const onChange =async (res) => {
        let params = [], fileList =  Array.prototype.slice.call(res)
        for(let i = 0; i < fileList.length; i++){
            let result = await loadFile(fileList[i])
            params.push(result)
        }      
        addAudio({list: params}).then(res=>{  // 调用后端接口
            if(res && res.code === 100){
                message.success('上传成功')
                updataList()   // 更新列表
            }
        })
    }

第二类:很多个异步,只要最后所有的执行结果

/**
 * Promise的静态方法all的重构(数组中所有的promise执行结束后,才会返回结果)
 * @param {*} list 
 * @returns 
 */
PromiseSelf.all = function(list){
    return new PromiseSelf((resolve,reject)=>{
        let done = gen(resolve,list.length)
        list.forEach((item,index)=>{
            item.then(value=>{
                done(index,value)
            })
        })
    })
}

function gen(resolve,length){
    let values = []
    return function(i,value){
        values[i] = value
        if(i === length - 1){
            resolve(values)
        }
    }
}

第三类:很多个异步,只要最后一次的执行结果(适用场景: 搜索时,每次输入要调用接口,接口得同步)

constructor(props){
    super(props)
    this.state = {
      searchResult: ''
    }
    this.queueList = []
  }

  handleSearch(type){   //文本改变
    return async (value)=>{
      this.pushQueue(value, []);   // 将每次输入内容放置到数组中
      let result = await this.handleSearchAPI(type, value);  // 等待每次请求
      this.queueList.forEach(element => { // 遍历数组,将当前接口返回的数据准确放置在对应的输入内容上
        if(element.key == value){ element.result = result; }
      });
      let searchResult = this.searchQueue[this.searchQueue.length - 1].result;  // 取数组中最后一项结果展示
      this.setState({ ...searchResult, });
     }
  }

  pushQueue(key, result){
    this.queueList.push({key, result});
  }

  handleSearchAPI(type, value, scroll = 0){ //请求接口优化
    return new Promise((resolve, reject) =>{
          trainCampSchool({   // 接口请求
            word:value || '',
            pageNum: this.searchPageNum,
            pageSize: this.searchPageSize,
          }).then(res=>{
            let schoolDataList=this.state.school.concat(res.data.dataList)
            resolve({
              school: schoolDataList
              scrollFlag:true
            })
          }).catch(err =>{
            reject(err);
          })
        } )
  }
<Select
            showSearch
            style={{ width: 136 }}
            placeholder="学校名称"
            allowClear={true}
            filterOption={false}
            value = {this.state.schoolName }
            onChange={this.handleChange('school')}
            onFocus={this.handleFocus('school')}
            onSearch={this.handleSearch('school')}
            onPopupScroll={this.handlePopupScroll('school')}
            getPopupContainer={triggerNode => triggerNode.parentElement}
            > 
              { 
                this.state.school?.map((item)=>
                  <Option value={item.schoolId} key={item.schoolId}>{item.fullName}</Option>
                )
              } 
</Select>
posted on 2022-04-14 18:48  94Lucky  阅读(530)  评论(0编辑  收藏  举报