基于nodejs服务端web组件化开发(五、异步数据请求)

61 阅读1分钟

五、异步数据请求

在上节的例子中,我们都是用静态的同步数据进行,实际中几乎使用的数据都是异步 这节先模拟建个组件

// Navbar.js
const { html, css, define } = require("hcdr")

// 模拟从数据库请求获取的异步数据
const list = async () => [
  { id: 1, title: "首页" },
  { id: 2, title: "新闻咨询" },
  { id: 3, title: "产品游览" },
  { id: 4, title: "关于" }
]

const template = async () => {
  const data = await list()
  return html`
    <ul class="navbar">
      ${data
        .map(function (item) {
          return html`<li><a href="/list/${item.id}">${item.title}</a></li>`
        })
        .join("\n")}
    </ul>
  `
}

const style = () => css`
  .navbar {
    display: flex;
  }
`

module.exports = define("Navbar", { template, style })

新建测试文件

// test4.js
const { render } = require("hcdr")

const Navbar = require("./Navbar")

console.log(render(Navbar))

运行后程序报错

TypeError: code.replace is not a function

实际是在 tag.js 中此时的 code 实际是Promise { <pending> },因此报错了因此这儿应改写为 Promise

// hcdr/index.js 修改define方法
// ...
let code = template(data || {})
if (code instanceof Promise) {
  return new Promise((resolve, reject) => {
    code
      .then(str => {
        resolve(compileTemplate(str, id))
      })
      .catch(err => reject(err))
  })
} else {
  return compileTemplate(code, id)
}

没有报错,但是没有显示出异步数据来

<!-- 结构内容 -->
[object Promise]

因此还应把render方法改为异步方法

// hcdr/index.js 修改render方法

async function render(tpl, data, css, config) {
  let strHtml = await tpl(data || {}, css || {})
  // ... 下面省略
}

调用时用异步方法调用

// test4.js 修改
// console.log(render(Navbar))
// 修改为
render(Navbar).then(code => console.log(code))

数据出来了

<!-- 结构内容 -->
<ul data-ulgbvw0o class="navbar">
  <li><a href="/list/1">首页</a></li>
  <li><a href="/list/2">新闻咨询</a></li>
  <li><a href="/list/3">产品游览</a></li>
  <li><a href="/list/4">关于</a></li>
</ul>

至此,整个流程基本梳理通了。 下节,看看全局配置完善我们的页面