Giter VIP home page Giter VIP logo

Comments (13)

langyo avatar langyo commented on June 3, 2024

from plasmolysis.

Alan-Liang avatar Alan-Liang commented on June 3, 2024

您是说静态分析吗?对于静态分析来说以下两者是完全一样的:

[
  a(),
  ...bMixin(),
  c(),
]

() => {
  a()
  bMixin()
  c()
}

静态的话都分析不出来是干嘛的。如果您说的是控制流的话,我的意思是类似 React Hooks 的方式,用户给的函数其实只在初始化的时候调用一遍(和数组的方式一样)。

from plasmolysis.

langyo avatar langyo commented on June 3, 2024

您是说静态分析吗?对于静态分析来说以下两者是完全一样的:

[
  a(),
  ...bMixin(),
  c(),
]

() => {
  a()
  bMixin()
  c()
}

静态的话都分析不出来是干嘛的。如果您说的是控制流的话,我的意思是类似 React Hooks 的方式,用户给的函数其实只在初始化的时候调用一遍(和数组的方式一样)。

值得考虑,但那样又得大规模重构了,,

再让我想想吧,,

from plasmolysis.

Alan-Liang avatar Alan-Liang commented on June 3, 2024

不过有个缺点就是写着写着习惯了就会写出if(...)doSth()这样的代码

from plasmolysis.

langyo avatar langyo commented on June 3, 2024

@Alan-Liang 其实呢,这个框架有一个尚未公开说明的特性,它能以比较优雅的方式实现您刚刚所说的判断执行

来看个例子:

[
  fetch(...),
  [
    ({ result }) => result === 'success',
    createModel('alert', { info: 'Login success!', color: 'green' })
  ],
  [
    ({ result }) => result === 'fail',
    createModel(({ reason }) => ({ type: 'alert', payload: { info: `Login failed, because ${reason}.`, color: 'red' }}))
  ]
]

每一个数组都是控制流,控制流内可以内嵌子控制流,并且子控制流的开头可以是一个返回布尔值的函数——函数执行后返回结果如果为 true,才会执行这个子控制流,否则越过这个子控制流

from plasmolysis.

Alan-Liang avatar Alan-Liang commented on June 3, 2024

对,我从最后一个例子的最后看出来了。也许可以这样?

() => {
  const { result, reason } = fetch(...)
  mark(result, 'success', createModel('alert', ...))
  mark(() => result.value === 'fail', createModel('alert', { info: () => `Login failed, because ${reason.value}`, color: 'red' }))
}

或者

markIf(result, 'success')
  .then(createModel(...))
  .else(createModel(...))

怎么看怎么像 DSL 😂

from plasmolysis.

Alan-Liang avatar Alan-Liang commented on June 3, 2024
const log = wrap(console.log.bind(console))
createAppOrSomething({
  // ...
  onSubmitLoginRequest() {
    const loginWaitingModel = createModel('waitDialog', { title: 'Logging in...' })
    const { name, password } = state
    log(() => `name is ${name.value}, password is ${password.value}`)
    log(unwrapRef`name is ${name}, password is ${password}`)
    const { state: loginState } = fetch('/api/login', { name, password })
    handleOnServer(
      markIf(searchDb({ collection: 'users', payload }).error)
        .then(reply({ state: 'success' }))
        .else(reply({ state: 'fail' }))
    )
    loginWaitingModel.destroy()
    markIf(loginState, 'success')
      .then(() => {
        const successInfoDialog = createDialog('infoDialog', { title: 'Login success!' })
        wait(3000)
        successInfoDialog.destroy()
      }).else(() => {
        const failInfoDialog = createDialog('infoDialog', { title: 'Login failed!' })
        wait(3000)
        failInfoDialog.destroy()
      })
  },
  // ...
})

变成这样:

onSubmitLoginRequest: [
  {
    type: 'create-model',
    payload: [ 'waitDialog', { title: 'Logging in...' } ],
    result: 'create-model-1',
  },
  {
    type: 'external-function-call',
    func: console.log.bind(console),
    payload: __state => `name is ${__state.name.value}, password is ${__state.password.value}`,
  },
  {
    type: 'external-function-call',
    func: console.log.bind(console),
    payload: __state => `name is ${__state.name.value}, password is ${__state.password.value}`, // unwrapRef 编译成这样
  },
  {
    type: 'fetch',
    payload: [ '/api/login', __state => ({ name: __state.name, password: __state.password }) ],
    result: 'fetch-2',
  },
  {
    type: 'handle-on-server',
    callback: [
      {
        type: 'mark-if',
        condition: [
          {
            type: 'search-db',
            payload: payload => [ { collection: 'users', payload } ],
            result: 'search-db-3',
            return: res => res.error,
          }
        ],
        then: [ { type: 'reply', payload: [ { state: 'success' } ] } ],
        else: [ { type: 'reply', payload: [ { state: 'fail' } ] } ],
      }
    ]
  },
  {
    type: 'destroy-model',
    payload: [ 'create-model-1' ],
  },
  {
    type: 'mark-if',
    cond: [
      {
        type: 'compare',
        payload: [
          {
            type: 'variable',
            name: 'fetch-2',
            return: res => res.state
          },
          {
            type: 'constant',
            value: 'success',
          },
        ],
      },
    ],
    then: [
      {
        type: 'create-dialog',
        payload: [ 'infoDialog', { title: 'Login success!' } ],
        result: 'create-dialog-4',
      },
      {
        type: 'wait',
        payload: [ 3000 ],
      },
      {
        type: 'destroy-dialog',
        payload: [ 'create-dialog-4' ],
      },
    ],
    else: [
      {
        type: 'create-dialog',
        payload: [ 'infoDialog', { title: 'Login failed!' } ],
        result: 'create-dialog-4',
      },
      {
        type: 'wait',
        payload: [ 3000 ],
      },
      {
        type: 'destroy-dialog',
        payload: [ 'create-dialog-4' ],
      },
    ],
  },
]

from plasmolysis.

langyo avatar langyo commented on June 3, 2024

from plasmolysis.

langyo avatar langyo commented on June 3, 2024

from plasmolysis.

Alan-Liang avatar Alan-Liang commented on June 3, 2024

TL; DR:这个函数是 全局 初始化的时候执行的,不应该直接包含任何对 payload、state 等的直接使用,虽然不可以 GC 但是反正一共就创建一次对象,不会造成内存泄漏。

嗯……我的意思是这个函数在全局初始化的时候就运行了,转成 这个评论 中的样子了(直接参考:Vue composition API),最后翻译出来和数组式的基本一样。对于 markIf,在执行的时候会 同时 执行 if 和 else 分支,最后转成这样:

      {
        type: 'mark-if',
        condition: [
          {
            type: 'search-db',
            payload: payload => [ { collection: 'users', payload } ],
            result: 'search-db-3',
            return: res => res.error,
          }
        ],
        then: [ { type: 'reply', payload: [ { state: 'success' } ] } ],
        else: [ { type: 'reply', payload: [ { state: 'fail' } ] } ],
      }

原生 if 是做不到这点的(除非您想学 Svelte)。

个人更喜欢 mark 是全局的(import { wrap, mark } from 'nickelcat'

from plasmolysis.

Alan-Liang avatar Alan-Liang commented on June 3, 2024

(其实 mark 只是我随便编的一个名字,建议不要使用)

from plasmolysis.

langyo avatar langyo commented on June 3, 2024

from plasmolysis.

Alan-Liang avatar Alan-Liang commented on June 3, 2024

orz

from plasmolysis.

Related Issues (1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.