6 回答

TA贡献1797条经验 获得超6个赞
问题是,这不是队列,而是foreach执行promise,递归一下就好了。
function doThing(file) {
return new Promise((resolve) => {
setTimeout(() => {
console.log('doThing', file)
resolve('result:' + file)
}, 500)
})
}
function queue(files, data = []) {
return new Promise((resolve) => {
if (files.length > 0) {
let file = files.shift();
doThing(file).then((res) => {
data.push(res)
resolve(queue(files, data))
})
} else {
resolve(data)
}
})
}
queue(['file1', 'file2', 'file3']).then(data => {
console.log(data);
});

TA贡献1824条经验 获得超5个赞
不知道,你是不是要达到 串行上传还是并行上传的目的 ?
// 下面是串行上传的
function queue(arr, handle) {
let index = 0
let length = arr.length
return new Promise((resolve, reject) => {
!(function next() {
try {
handle(arr[index])
.then(function () {
++index < length
? next()
: resolve()
})
.catch(reject)
} catch (err) {
reject(err)
}
})()
})
}
function upload(file) {
return new Promise((resolve, reject) => {
// 上传文件
setTimeout(function () {
console.log(`upload ${file}`)
resolve()
}, file * 1000 )
})
}
queue(['3', '2', '1'], upload).then(data => {
console.log('ok');
}).catch(err => {
console.log('error', err)
})

TA贡献1895条经验 获得超3个赞
楼主我来对你的代码做点注释,你自己再看看问题出在哪里
// 定义一个队列构造器
function queue(files) {
// 使用Promise.resolve(val)生成一个Promise实例promise
// promise的状态已转换为Resolved状态,
// 这时promise仍可通过then方法获取到Resolved的结果val(这里的val为空,所以是undefined)
let promise = Promise.resolve();
// 遍历一次传入的数组
files.forEach(file => {
// promise对象添加then方法,并将then方法的返回值重新赋值给promise并传入resolve回调,
// 因为只传了一个函数(这个函数没有参数,所以没法捕获上一次操作完成返回的值,
// 事实上,楼主也没有在每次完成返回值,因为resolve()中没有给值。)参数,
// 所以reject的回调为undefined
promise = promise.then(() => {
// then.resolve回调中返回了一个新的Promise实例,新的实例通过构造的方式生成,
// 构造传入了"resolve"这样一个名字的函数参数,作为promise的resolve回调,没有reject
return new Promise(resolve => {
// 新构造的Promise实例的resolve回调中执行异步上传方法
doThing(file, () => {
//上传操作,访问接口
// 上传完成resolve这个promise,但是没有给下一个操作传入值,
// 所以最后调用的data为空
resolve();
});
});
});
});
// 返回了新的promise引用,事实上,这个promise引用就已经是个队列了
return promise;
}
// 这一步调用之后,做了什么事情?从这里再看这个queue内部的执行过程,
// 调用之后,第一个上传文件的操作就会立即启动,上传完成之后就会继续上传下一个,
// 直到这数组中都传完, 最后一个操作的resolve被下面这个then捕获
queue([file1, file2, file3])
//获取了最后一个promise实例成功后resolve的值
.then(data => {
// 打印resolve的值
console.log(data);
});
添加回答
举报