V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
cs5117155
V2EX  ›  PHP

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

  •  
  •   cs5117155 · Oct 7, 2021 · 2978 views
    This topic created in 1664 days ago, the information mentioned may be changed or developed.
    //查询是否有 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 replies    2021-10-09 14:28:48 +08:00
    imdong
        1
    imdong  
       Oct 7, 2021 via iPhone
    最简单的但可能不是好的解决方案,

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

    起码可以避免嵌套太多的问题,如果能用 class 更好,具体没用过 workeman
    airqj
        2
    airqj  
       Oct 7, 2021 via Android
    作者好像说建议优先使用 redis 库
    zjsxwc
        3
    zjsxwc  
       Oct 7, 2021
    学习 js 用 php 版本的 promise

    https://github.com/reactphp/promise
    mywaiting
        5
    mywaiting  
       Oct 7, 2021
    多年没有看 PHP,万万没有想到 PHP 现在也能写成 JS 了

    Callback -> Promise -> Await/Async,所有编程语言都逃不过的异步坑
    learningman
        6
    learningman  
       Oct 7, 2021
    async/await
    cs5117155
        7
    cs5117155  
    OP
       Oct 8, 2021
    @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  
       Oct 8, 2021
    @cs5117155
    因为你都用了同一个 promise,
    而实际应该和我一样使用两个不同的 promise,
    因为一个 promise 一旦 resolve 了它就凉凉了
    :doge:
    cs5117155
        10
    cs5117155  
    OP
       Oct 9, 2021
    @zjsxwc 按照你不同的 promise 还真可以了,我有个好奇,你是怎么搜到 `https://sergeyzhuk.me/2017/06/16/phpreact-promises/` 。我找谷歌搜到都是官网文档的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5627 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 53ms · UTC 01:35 · PVG 09:35 · LAX 18:35 · JFK 21:35
    ♥ Do have faith in what you're doing.