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>