promise 介绍

promise是异步编程的一种解决方法,比传统的回调函数和事件更合理更强大。

他由社区最早提出和实现,ES6将其写进语言标准,统一了用法,原生提供了promise对象。

所谓promise,简单说是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,从语法上说,promise是一个对象,从它可以获取异步操作的消息,promise提供了统一的API,各种异步操作都可以用同样的方法进行处理。

promise 用法

promise对象是一个构造函数,用来生成promise实例。

创建一个promise对象实例

var promise = new Promise(function( resolve, reject) {
       //some code 
      if(//异步操作成功){
        resolve(value);
      }else{
        reject(error);
      }
});

Promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject,他们是两个函数,由Javascript引擎提供,不用自己部署。

resolve函数的作用是,将promise对象的状态从“pending”变为‘’resolved‘’,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数

then 用法

promise.then(
    function(value){
   //success
   },
    function(error){
   //failure
 });

then方法可以接受连个回调函数作为参数,第一个回调函数是promise对象的状态变为resolved时调用,第二个回调函数是promise对象的状态变为rejected时调用,其中,第二个函数是可选的,不一定要提供,这两个函数都接受promise对象传出的值作为参数;

promise对象的简单例子

function timeOut (ms) {
   return new Promise(function(resolve,reject) {
        return  setTimeout(resolve, ms, "done");
   })
}

timeOut(3000).then(function(value){
    console.log(value);
})

上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。

Promise 新建后就会立即执行。

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。

promise 例子

function test(name) {
    return new Promise(
        function (resolve, reject) {
            console.log(name + ' begin');
            setTimeout(function () {
                console.log(name + ' finished');
                resolve(name)
            }, Math.random() * 1000);
        }
    )
}

test('t1').then(function () {
    return test('t2')
});

安装 php 以及 xdebug 扩展

配置 xdebug

需要注意的是,自从 PHP 5.3 开始, 你需要使用 'zend_extension', 不能使用 'zend_extension_ts', 'zend_extension_debug' 或者 'extension'。

zend_extension="/usr/lib/php/20170718/xdebug.so" # 关键,之前写的是 extension 不可以,需要加前缀 zend_
xdebug.remote_enable = 1 # 关键,需要开启
xdebug.remote_host = "127.0.0.1"
xdebug.remote_port = "9001" #关键,定义监听端口, phpstorm 需要做相应的配置

xdebug.remote_log="var/log/xdebug/xlog"
xdebug.remote_autostart = 1

xdebug.idekey = "PHPSTORM"
xdebug.show_error_trace = 1
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp/xdebug-someuser/"
xdebug.profile_enable_trigger=1
xdebug.trace_enable_trigger=1

需要注意,字符串用双引号引起来

phpstorm 配置

  • 设置解释器
  • 设置站点
  • 增加 debug 用例

phpstorm 验证

  • phpstorm 有一个 valiate 功能,用于验证配置是否正确。

断点调试测试

配置完成之后,打个断点试试看。

参考

在 laravel 开发中遇到了这样的问题,业务代码中调用 env() 获取环境变量,结果无法获取。

原因如官方文档所述:

为了给你的应用程序提升速度,你应该使用 Artisan 命令 config:cache 将所有的配置文件缓存到单个文件中。这会把你的应用程序中所有的配置选项合并成一个单一的文件,然后框架会快速加载这个文件。
通常来说,你应该把运行 php artisan config:cache 命令作为生产环境部署常规的一部分。这个命令不应在本地开发环境下运行,因为配置选项在应用程序开发过程中是经常需要被更改的。
如果在部署过程中执行 config:cache 命令,那你应该确保只从配置文件内部调用 env 函数。

意思是说,在你的业务代码中,不能使用 env() 方法。

原因何在?

在 Laravel 中,如果执行 php aritisan config:cache 命令,Laravel 将会把 app/config 目录下的所有配置文件“编译”整合成一个缓存配置文件到 bootstrap/cache/config.php,每个配置文件都可以通过 env 函数读取环境变量,这里是可以读取的。但是一旦有了这个缓存配置文件,在其他地方使用 env 函数是读取不到环境变量的,所以返回 null.

让我们看看这段代码,Illuminate/Foundation/Bootstrap/DetectEnvironment.php line 18:

public function bootstrap(Application $app)
{
    if (! $app->configurationIsCached()) {
        $this->checkForSpecificEnvironmentFile($app);

        try {
            (new Dotenv($app->environmentPath(), $app->environmentFile()))->load();
        } catch (InvalidPathException $e) {
            //
        }
    }
}

这个方法在框架启动后就会运行,如果存在缓存配置文件,就不会去设置环境变量了。

因此,在配置文件即 app/config 目录下的其他地方,读取配置不要使用 env 函数去读环境变量,这样你一旦执行 php artisan config:cache 之后,env 函数就不起作用了。所有要用到的环境变量,在 app/config 目录的配置文件中通过 env 读取,其他地方要用到环境变量的都统一读配置文件而不是使用 env 函数读取。

环境:

  • ubuntu 16.04
  • php7.2

一、安装 php7.2-dev

apt-get install php7.2-dev -y

二、下载并编译 xdebug

  • 下载 xdebug 最新的源码包
wget https://xdebug.org/files/xdebug-2.6.0.tgz
  • 解压缩
tar -zxvf xdebug-2.6.0.tgz
  • 编译安装
cd xdebug-2.6.0
phpize
/configure --enable-xdebug
make
make install

三、配置

  • 在 cd /etc/php/7.2/mods-available 目录中,增加 xdebug.ini
extension=xdebug.so
xdebug.remote_enable = 1
xdebug.remote_port = 9001
xdebug.idekey = PHPSTORM
xdebug.show_error_trace = 1
xdebug.remote_autostart = 0
xdebug.file_link_format = phpstorm://open?%f:%l
  • 增加软连接
cd /etc/php/7.2/fpm/conf.d/
sudo ln -s /etc/php/7.2/mods-available/xdebug.ini 20-xdebug.ini
cd /etc/php/7.2/cli/conf.d/
sudo ln -s /etc/php/7.2/mods-available/xdebug.ini 20-xdebug.ini

四、测试

  1. cli 环境下,查看 php -m
  2. 测试 phpinfo,查看 xdebug 的信息 (略)
  3. phpstorm 测试 xdebug

在 openresty 中,要对部分特殊的 url 进行 rewrite,由于 url 比较多,还经常变动,rewrite 时还需要做判断,因此考虑使用 lua 进行处理。

在这个过程中,希望把特殊的 url 作为配置文件写入 table,然后进行判断,那么 lua 如何读取一个配置文件呢?

其实很简单,在 lua 脚本中使用 dofile 即可:

dofile "myconfig.lua"
dofile "/usr/share/myapp/config.lua"

这样的方式比较简单,但是如果遇到错误,会导致整个程序停止运行,如果你希望在遇到读取文件发生错误的时候抛出异常,可以使用以下的方式:

local ok,e = pcall(dofile,"myconfig.lua")
if not ok then
  -- handle error; e has the error message
end