Promise 中如何 sleep(不是实现 sleep)

2018-06-27 11:46:55 +08:00
 lolizeppelin

我的函数原型如下


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 中需要等待要如何写..有点懵比了

3898 次点击
所在节点    程序员
20 条回复
sethverlo
2018-06-27 11:48:03 +08:00
coderfox
2018-06-27 11:55:38 +08:00
删掉 await new Promise 的包装。
因为 new Promise 那里接受一个闭包参数,闭包函数不是 async,所以不能在其中使用 await。
没有必要在 async 函数中还手动构造 Promise 然后 await 掉。
建议重新学学 Promise。
lolizeppelin
2018-06-27 11:57:07 +08:00
await new Promise 是为了等待这个 Promise 结束以后才调用 handleLoadingClose, 故意那样写的谢谢
lolizeppelin
2018-06-27 11:58:44 +08:00
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));
}
hahastudio
2018-06-27 12:01:17 +08:00
主要是不是丢给 promise 的函数没有 async 啊
orzfly
2018-06-27 12:01:27 +08:00
唉,你的 forEach 后的函数没有带 async 修饰字,而且 forEach 也不支持 Promise,所以不能用 await。你可以用原生的 for 循环代替 forEach,或者用 Bluebird.map 等函数代替 forEach。
orzfly
2018-06-27 12:02:42 +08:00
所以,限制并发的话,也可以试试 Bluebird.map(..., ..., { concurrency: 5 })。
lolizeppelin
2018-06-27 12:04:24 +08:00
@sethverlo
谢谢...但这个也不好用 我想要能阻塞住 this.state.list.forEach((pkginfo)

delay 的实现不了啊.....

如果不行的话我只能写个大循环, 每次先先判断是否到并发上限....到上限就延迟...没到上限就扫描 this.state.list

每次还要把已经完成的从 this.state.list 移出去....写起来忒难看
lolizeppelin
2018-06-27 12:11:29 +08:00
@orzfly

可以了....谢谢你的提醒 要的就是这个效果

this.state.list.forEach(async (pkginfo)

就可以了!!!! 3q
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,等待达成进入条件
lolizeppelin
2018-06-27 12:29:02 +08:00
@lovedebug

不能等 10 个完成...再下一批 10 个....

要做到完成一个 下一个立刻上....

用 sleep 已经算偷懒写法了..... 正确的写法应该是完成的直接 yeid 过去...js 我没那么熟悉 sleep 解决就算了
lovedebug
2018-06-27 13:11:14 +08:00
考虑 node 的库吧。或者自己内部写个定时器。周期性检测是否可以执行。
lovedebug
2018-06-27 13:13:46 +08:00
如果单纯要连续做任务,换成队列不断的取就可以。类似 Java 线程池。
momocraft
2018-06-27 13:49:53 +08:00
你需要 delay 的其实是开始而不是结束,Promise 对象生成时那个任务已经开始了,再想想吧。
famiko
2018-06-27 13:52:59 +08:00
限制并发。。Promise.race 了解一下
jimliang
2018-06-27 14:08:53 +08:00
bluebird 的 Promise 支持修改并发数
http://bluebirdjs.com/docs/api/promise.map.html
```
...map(..., {concurrency: 3});
```
lolizeppelin
2018-06-27 14:18:01 +08:00
@momocraft
并不是 delay 完就能执行啊.....delay 完我还要判断是否达到上限,还是在上限还得 delay 啊.....

@jimliang
谢谢提供新的解决方法....不过这边已经解决了就不引入更多的库了
jimliang
2018-06-27 20:48:57 +08:00
@lolizeppelin 不一定要引库,只是作为参考自己写一个并发控制的逻辑
wangjie
2018-06-28 01:08:34 +08:00
@lolizeppelin #3 2l 就指出了你的语法错误所在你还没有意识到 XD

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/466226

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX