我的函数原型如下
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); class GversionsBulkUpdate extends React.Component { ...... update = async () => { const { handleLoadingClose, handleLoading, appStore } = this.props; handleLoading(); let bulkMax = 10; // 最大并发值 const fails = []; await new Promise((resolve) => { const isFinish = finish(this.state.list.length, resolve); // finish mark this.state.list.forEach((pkginfo) => { while (bulkMax <= 0) await sleep(300); // 限制并发数量 bulkMax -= 1; const body = { address: pkginfo.url, gversion: pkginfo.gversion, ftype: pkginfo.ftype }; goGameRequest.createPfile(appStore.user, pkginfo.pkg.package_id, body, () => { console.log('finish one'); bulkMax += 1; isFinish.next(); }, // error callback (msg) => { // success callback console.log(msg); bulkMax += 1; isFinish.next(); fails.push({ pkg: pkginfo.pkg, msg }); }); }); }); console.log(fails) const msg = fails.length === 0 ? '批量更新执行完毕' : '部分包更新失败'; handleLoadingClose(msg); this.setState({ parameters: Object.assign({}, BaseParameters), list: Object.assign([], baseList), packages: Object.assign([], this.pacakges) }); }; ......
createPfile 是个 http 请求
想用 while (bulkMax <= 0) await sleep(300); 限制并发请求数量
但是语法错误....Promise 中需要等待要如何写..有点懵比了
![]() | 1 sethverlo 2018-06-27 11:48:03 +08:00 |
![]() | 2 coderfox 2018-06-27 11:55:38 +08:00 via Android 删掉 await new Promise 的包装。 因为 new Promise 那里接受一个闭包参数,闭包函数不是 async,所以不能在其中使用 await。 没有必要在 async 函数中还手动构造 Promise 然后 await 掉。 建议重新学学 Promise。 |
3 lolizeppelin OP await new Promise 是为了等待这个 Promise 结束以后才调用 handleLoadingClose, 故意那样写的谢谢 |
4 lolizeppelin OP |
![]() | 5 hahastudio 2018-06-27 11:58:59 +08:00 https://stackoverflow.com/questions/951021/what-is-the-Javascript-version-of-sleep function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } |
![]() | 6 hahastudio 2018-06-27 12:01:17 +08:00 主要是不是丢给 promise 的函数没有 async 啊 |
![]() | 7 orzfly 2018-06-27 12:01:27 +08:00 via Android 唉,你的 forEach 后的函数没有带 async 修饰字,而且 forEach 也不支持 Promise,所以不能用 await。你可以用原生的 for 循环代替 forEach,或者用 Bluebird.map 等函数代替 forEach。 |
![]() | 8 orzfly 2018-06-27 12:02:42 +08:00 via Android 所以,限制并发的话,也可以试试 Bluebird.map(..., ..., { concurrency: 5 })。 |
9 lolizeppelin OP @sethverlo 谢谢...但这个也不好用 我想要能阻塞住 this.state.list.forEach((pkginfo) delay 的实现不了啊..... 如果不行的话我只能写个大循环, 每次先先判断是否到并发上限....到上限就延迟...没到上限就扫描 this.state.list 每次还要把已经完成的从 this.state.list 移出去....写起来忒难看 |
10 lolizeppelin OP |
![]() | 11 lovedebug 2018-06-27 12:17:31 +08:00 this.state.list.forEach 最好换成 await Promise.all(this.state.list.map(async (pkginfo) =>{}) 既然你限制并发数,还用 forEach,每次取 10 个做不好吗?多余的 return,等待达成进入条件 |
12 lolizeppelin OP @lovedebug 不能等 10 个完成...再下一批 10 个.... 要做到完成一个 下一个立刻上.... 用 sleep 已经算偷懒写法了..... 正确的写法应该是完成的直接 yeid 过去...js 我没那么熟悉 sleep 解决就算了 |
![]() | 13 lovedebug 2018-06-27 13:11:14 +08:00 考虑 node 的库吧。或者自己内部写个定时器。周期性检测是否可以执行。 |
![]() | 14 lovedebug 2018-06-27 13:13:46 +08:00 如果单纯要连续做任务,换成队列不断的取就可以。类似 Java 线程池。 |
![]() | 15 momocraft 2018-06-27 13:49:53 +08:00 你需要 delay 的其实是开始而不是结束,Promise 对象生成时那个任务已经开始了,再想想吧。 |
16 famiko 2018-06-27 13:52:59 +08:00 限制并发。。Promise.race 了解一下 |
![]() | 17 jimliang 2018-06-27 14:08:53 +08:00 bluebird 的 Promise 支持修改并发数 http://bluebirdjs.com/docs/api/promise.map.html ``` ...map(..., {concurrency: 3}); ``` |
18 lolizeppelin OP |
![]() | 19 jimliang 2018-06-27 20:48:57 +08:00 @lolizeppelin 不一定要引库,只是作为参考自己写一个并发控制的逻辑 |
![]() | 20 wangjie 2018-06-28 01:08:34 +08:00 via Android @lolizeppelin #3 2l 就指出了你的语法错误所在你还没有意识到 XD |