V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cs5117155
V2EX  ›  PHP

使用 workeman/redis 时,如何才能避免回调地狱

  •  
  •   cs5117155 · 2021-10-07 10:17:15 +08:00 · 2045 次点击
    这是一个创建于 894 天前的主题,其中的信息可能已经有所发展或是发生改变。
    //查询是否有 key
    $redis->get('key', function ($result, $redis)use($db){
        //设置 key2
        $redis->set('key2', 'value2', function ($result)use($db) {
            var_dump($result);
            //更新数据库
            $row_count = $db->update('Persons')->cols(array('sex'))->where('ID=1')
           ->bindValue('sex', 'F')->query();
        });
    })
    

    如果这样我写的话,已经超过 3 层回调了,如果还需要再更新数据库里面发送一个异步 Http 请求(workerman/http-client),这样岂不是又多了一两层? 我该如何修改这个写法,才能像同步代码写法

    10 条回复    2021-10-09 14:28:48 +08:00
    imdong
        1
    imdong  
       2021-10-07 10:45:22 +08:00 via iPhone
    最简单的但可能不是好的解决方案,

    $call_a = function …
    $redis->get(…, $call_a);

    起码可以避免嵌套太多的问题,如果能用 class 更好,具体没用过 workeman
    airqj
        2
    airqj  
       2021-10-07 11:01:54 +08:00 via Android
    作者好像说建议优先使用 redis 库
    zjsxwc
        3
    zjsxwc  
       2021-10-07 11:06:30 +08:00
    学习 js 用 php 版本的 promise

    https://github.com/reactphp/promise
    zjsxwc
        4
    zjsxwc  
       2021-10-07 11:40:48 +08:00
    mywaiting
        5
    mywaiting  
       2021-10-07 12:53:24 +08:00
    多年没有看 PHP,万万没有想到 PHP 现在也能写成 JS 了

    Callback -> Promise -> Await/Async,所有编程语言都逃不过的异步坑
    learningman
        6
    learningman  
       2021-10-07 23:10:39 +08:00
    async/await
    cs5117155
        7
    cs5117155  
    OP
       2021-10-08 10:42:08 +08:00
    @zjsxwc
    ```php
    $charecabinet_id =33;
    $getDeferred = new React\Promise\Deferred();
    $initialPromise = $getPromise =$deferred= $getDeferred->promise();


    $initialPromise->then(function() use($redis,$initialPromise){

    $redis->set('key2', 'value32', function ($result)use($initialPromise) {
    $initialPromise->resolve($result);
    });

    return $initialPromise;
    })->then(function($result)use($charecabinet_id,$initialPromise){
    var_dump($charecabinet_id);
    $row_count = self::$db->update('xxx')
    ->cols(array('heart_time'=>time()))
    ->where("ID=$charecabinet_id")->query();

    return $initialPromise->resolve($row_count);
    })->otherwise(function (\Throwable $x) {
    // Propagate the rejection
    echo 'Reject ' . $x->getMessage(); // 3
    });
    ```
    我参考你的写法,发现只运行到设置 key2=value32,第二个`then`没有运行下去了,是哪里姿势不对吗
    zjsxwc
        8
    zjsxwc  
       2021-10-08 15:49:50 +08:00
    @cs5117155
    因为你都用了同一个 promise,
    而实际应该和我一样使用两个不同的 promise,
    因为一个 promise 一旦 resolve 了它就凉凉了
    :doge:
    cs5117155
        10
    cs5117155  
    OP
       2021-10-09 14:28:48 +08:00
    @zjsxwc 按照你不同的 promise 还真可以了,我有个好奇,你是怎么搜到 `https://sergeyzhuk.me/2017/06/16/phpreact-promises/` 。我找谷歌搜到都是官网文档的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5463 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 08:12 · PVG 16:12 · LAX 01:12 · JFK 04:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.