0%

安装 Go2Shell,把 Go2Shell 的图标拉到 Finder 里面,从而可以从 Finder 点击打开 Terminal

Async/AwaitPromise 的语法糖,有了 async/await 我们可以以一种更简便的方式来实现 Promise 的功能

Async

async 函数, async 被放置在一个函数前面,就像下面这样:

1
2
3
async function f() {
return 1
}

函数前面的 async 一词意味着一个简单的事情:这个函数总是返回一个 promise,如果代码中有 return <非promise> 语句, JavaScript 会自动把返回的这个 value 值包装成 promiseresolved 值。

例如,上面的代码返回 resolved 值为 1promise

1
2
3
4
async function f() {
return 1
}
f().then(alert) // 1

我们也可以显式的返回一个 promise,这个将会是同样的结果:

1
2
3
4
async function f() {
return Promise.resolve(1)
}
f().then(alert) // 1

所以,async 确保了函数返回一个 promise,即使其中包含非 promise

还有另外一个关键词 await,只能在 async 函数里使用。

Await

语法如下:

1
2
// 只能在 async 函数内部使用
let value = await promise

关键词 await 可以让 JavaScript 进行等待,直到一个 promise 执行并返回它的结果,JavaScript 才会继续往下执行。

例子:

1
2
3
4
5
6
7
8
async function f() {
let promise = new Promise(resolve => {
setTimeout(() => resolve(1), 1000)
})
let result = await promise // 等待,直到 promise 返回一个 resolve 值
alert(result) // 1
}
f()

注意事项

  • 不能在常规函数里使用 await
  • await 不能工作在顶级作用域

总结

  • 放在一个函数前面的 async 有两个作用
    • 使函数总是返回一个 promise
    • 允许在这其中使用 await
  • promise 前面的 await 关键字能够使 JavaScript 等待,直到 promise 处理结束。然后:
    • 如果它是一个错误,异常就产生了,就像在哪个地方调用了 throw error 一样
    • 否则,它会返回一个结果,我们可以将它分配给一个值
  • async/await 一起提供了一个很好的框架来编写易于读写的异步代码,有了 async/await,我们很少需要写 promise.then/catch, 但是我们仍然不应该忘记它们是基于 promise 的。

背景

  • 在模块化开发的场景下,有时候需要把所有模块切换到某一个分支,这个时候如果一个个模块去切换,使用的时间会很长,而且很繁琐,所以有了 "切换所有模块到某一个分支" 的功能
  • 同样,拉取最新代码也是,如果一个个模块去拉取,耗时会很长,有时候如果遗漏也不知道
  • "切换 env", 快速切换到某一个开发环境的配置
  • Artisan 命令太多需要搜索?
  • 想知道某个接口是谁写的?试试 Api Blame

功能

  • 辅助开发人员快速进行某些重复性操作

系统要求

  • 安装了 git

安装

配置

  • Foundation 路径

介绍

  • 切换到某一分支: 根据配置的 Foundation 路径,切换 Foundation 以及所有子模块的 git 仓库到某一个分支(切换之前,如果有未提交代码,会先 git stash,切换之后再 git stash pop
  • 拉取所有模块: 根据配置的 Foundation 路径,拉取 Foundation 以及所有子模块的 git 仓库当前分支的最新代码
  • 切换 env: 根据配置的 Foundation 路径,切换开发环境配置(点击切换)
  • Artisan 命令: 根据配置的 Foundation 路径,获取所有可用的 artisan 命令,并且根据标签分组,另外可以输入关键字搜索
  • Api Blame: 有时候路由和 url 不是很对应,会需要搜索来查找对应的控制器和方法,使用这个功能可以直接根据输入的完整 url 来确定位于什么控制器、什么方法

实现方式

  • 基于 electron-vue 开发,大部分操作通过 php 调用系统命令执行,少数通过 node 调用系统命令执行。

FAQ

  • 为什么某一个模块的代码没有切换到某一个分支?一般是代码冲突了,需要自行解决冲突
  • 为什么 "系统信息" 不展示版本信息?需要启动虚拟机并开启 swoole http server
  • 执行系统命令报错?检查 FoundationHomestead 路径是否配置正确(系统配置菜单)
  • 为什么 Foundation 路径有两个反斜杠?因为只有一个斜杠的时候会引起错误的转义
  • 刚刚写了个命令, 为什么 Artisan命令 里面不显示?因为有缓存十分钟的机制
  • 为什么 "确定" 按钮被禁用?某些检查不通过(如 Foundation 或者 Homestead 路径配置不正确)

1. 模型属性不知道哪里修改?

直接覆盖模型的 setAttribute 方法,监测到某一个属性改动的时候,抛一个异常就可以看到堆栈了

1
2
3
4
5
6
7
8
9
10
11
12
13
use Illuminate\Database\Eloquent\Model;

class Person extends Model
{
public function setAttribute($key, $value)
{
if ($key == 'xxx') { // 'xxx' 是你想要监听的属性
throw new \RuntimeException;
}

return parent::setAttribute($key, $value);
}
}

有多个地方修改?抛异常,捕获写 log,然后去 log 里面看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Illuminate\Database\Eloquent\Model;

class Person extends Model
{
public function setAttribute($key, $value)
{
if ($key == 'xxx') { // 'xxx' 是你想要监听的属性
try {
throw new \RuntimeException;
} catch (\RuntimeException $e) {
\Log::error($e->getTraceAsString());
}
}

return parent::setAttribute($key, $value);
}
}

2. Try to get property of non-object ?

1
2
3
$a = null;

var_dump($a->c);

对于这种场景,我们也可以 try catch,然后在异常处理里面 dump 上下文一些关键的变量、对象这些东西。