猿问

关于js promise队列的疑问

学习promise的过程中遇到一个关于队列的问题,在开发中遇到一个问题,需要循环请求上传的接口,但是下面的的方法好像没有做到队列,跪求大神帮我改造


需求是执行完一个再执行一个,直到最后一个,串行,对列的概念也不是很懂


function queue(files) {

  let promise = Promise.resolve();

  files.forEach(file => {

    promise = promise.then(() => {

      return new Promise(resolve => {

         doThing(file, () => {

           //上传操作,访问接口

             resolve();

           });

      });

    });

  });

  return promise;

}


queue([file1, file2, file3]).then(data => {

  console.log(data);

});


人到中年有点甜
浏览 618回答 6
6回答

慕尼黑5688855

一个promise的resolve只能使用一次,第二次以后的使用都是无效的你需要RxJs

互换的青春

问题是,这不是队列,而是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);});

沧海一幻觉

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

蛊毒传说

楼主我来对你的代码做点注释,你自己再看看问题出在哪里// 定义一个队列构造器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); });

四季花海

你队列的做法没问题,只是最后没有返回 data 而已。如果你需要 data 的话,可以在 resolve() 里返回。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答