Promise 中如何 sleep(不是实现 sleep) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
lolizeppelin
V2EX    程序员

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

 
  •   lolizeppelin 2018-06-27 11:46:55 +08:00 4423 次点击
    这是一个创建于 2662 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我的函数原型如下

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

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

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

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

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

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

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

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

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

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

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

    @jimliang
    谢谢提供新的解决方法....不过这边已经解决了就不引入更多的库了
    jimliang
        19
    jimliang  
       2018-06-27 20:48:57 +08:00
    @lolizeppelin 不一定要引库,只是作为参考自己写一个并发控制的逻辑
    wangjie
        20
    wangjie  
       2018-06-28 01:08:34 +08:00 via Android
    @lolizeppelin #3 2l 就指出了你的语法错误所在你还没有意识到 XD
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1107 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 23:10 PVG 07:10 LAX 16:10 JFK 19:10
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86