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

2021-10-07 10:17:15 +08:00
 cs5117155
//查询是否有 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),这样岂不是又多了一两层? 我该如何修改这个写法,才能像同步代码写法

2086 次点击
所在节点    PHP
10 条回复
imdong
2021-10-07 10:45:22 +08:00
最简单的但可能不是好的解决方案,

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

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

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

Callback -> Promise -> Await/Async,所有编程语言都逃不过的异步坑
learningman
2021-10-07 23:10:39 +08:00
async/await
cs5117155
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
2021-10-08 15:49:50 +08:00
@cs5117155
因为你都用了同一个 promise,
而实际应该和我一样使用两个不同的 promise,
因为一个 promise 一旦 resolve 了它就凉凉了
:doge:
zjsxwc
2021-10-08 16:34:53 +08:00
cs5117155
2021-10-09 14:28:48 +08:00
@zjsxwc 按照你不同的 promise 还真可以了,我有个好奇,你是怎么搜到 `https://sergeyzhuk.me/2017/06/16/phpreact-promises/` 。我找谷歌搜到都是官网文档的

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

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

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

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

© 2021 V2EX