我的函数原型如下
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
|