• Welcome to Journal web site.

我是 PHP 程序员

- 开发无止境 -

Next
Prev

第19章 0412-fetch async module介绍

Data: 2020-04-19 12:47:40Form: JournalClick: 0

demo1:异步调用原理
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise-1</title>
</head>

<body>
    <script>
        // cps
        // 定时器, 文件操作, 网络操作
        function createFile(success, failure) {
            success();
            failure();
        }

        function success(result) {
            return 'success ' + result;
        }

        function failure(error) {
            return 'failure ' + error;
        }

        // 传统
        createFile(success, failure);

        // cps: 尾部调用, 让用户产生一个错觉, 代码是同步执行,并不异步
        // 异步是乱序执行, 同步就必须按照一定的顺序
        // createFile()  -> Promise
        createFile().then(success).then(json).catch(failure);
    </script>
</body>

</html>
demo2:浏览器自带异步操作 Fetch API
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fetch API</title>
</head>

<body>
    <button onclick="getUser(this,url)">用户信息: fetch()</button>
    <script>
        // fetch(url).then(success)
        // fetch('https://jsonplaceholder.typicode.com/users')
        //     .then(response => response.json())
        //     .then(json => console.log(json))

        fetch('http://xhr411.edu/users.php')
            .then(response => response.json())
            .then(json => console.log(json))

        // ecma2017, async , await 来简化fetch

        // 必须将该函数 getUser声明为异步的(加上 async 为异步函数)
        //await 为等待数据返回
        let url = 'http://xhr411.edu/users.php';
        async function getUser(btn, url) {
            // fetch 异步请求,需要一个不确定的等待时间
            // 接口url
            const response = await fetch(url)
                // response是响应对象,response.json()
                // then(response=>response.json()) 将返回对象转换为json
            const result = await response.json();

            console.log(result);

            // 将接口数据渲染到页面中
            render(result, btn)

            // 实际就三步
            // 1. fetch: 发请求,返回响应对象response
            // 2. response.json: 将响应数据转为json格式
            // 3. 将json渲染到页面中

            // axios

        }
    </script>
    <script src="function.js"></script>
</body>

</html>
// function.js
// 渲染用户数据到页面中
function render(data, btn) {
    // 1. 如果是数组,则创建表格展示
    if (Array.isArray(data)) {
        // 创建表格
        const table = document.createElement('table');
        // 设置表格样式
        table.border = 1;
        table.cellPadding = 3;
        table.cellSpacing = 0;
        table.width = 360;

        // 设置标题
        const caption = table.createCaption();
        caption.textContent = '用户信息列表';
        caption.style.fontSize = '18px';
        caption.style.fontWeight = 'bolder';
        caption.style.marginBottom = '8px';
        // 创建表头
        const thead = table.createTHead();
        thead.style.backgroundColor = 'lightcyan';
        thead.innerHTML = '<tr><th>ID</th><th>用户名</th><th>邮箱</th></tr>';

        // 创建表格主体
        const tbody = table.createTBody();
        tbody.align = 'center';

        // 遍历数组
        data.forEach(user => {
            let html = `
                <tr>
                  <td>${user.id}</td><td>${user.name}</td><td>${user.email}</td>
                </tr>
              `;
            // 插入到表格中
            tbody.insertAdjacentHTML('beforeEnd', html);
        });

        // 防止重复生成表格,应该判断一下当前按钮的下一个兄弟是否是表格
        if (btn.nextSibling.tagName !== 'TABLE') {
            btn.after(table);
        }
    }
    // 2. 如果是单个对象,则用列表渲染
    else {
        // 创建列表元素,用于显示用户信息
        const ul = document.createElement('ul');

        // 使用模板字面量,快速创建用户数据
        ul.innerHTML = `
            <li>ID : <span class="user">${data.id}</span></li>
            <li>用户名 : <span class="user">${data.name}</span></li>
            <li>邮箱 : <span class="user">${data.email}</span></li>
          `;

        // 与上面功能一样,也是为了防止重复创建列表
        if (btn.nextSibling.tagName !== 'UL') {
            btn.after(ul);
            // 添加自定义样式,将用户信息高亮显示
            document.querySelectorAll('ul li .user').forEach(item => (item.style.color = 'red'));
        }
    }
}
demo3:立即执行函数
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模块-1</title>
</head>

<body>
    <script>
        // 模块: 有独立的功能以及相关的数据, 像对象
        // IIFE: 立即执行函数
        let user = (function(username, email) {
            let salary = 123456;
            return {
                username,
                email,
                salary,
                show() {
                    return `username: ${this.username},\nemail: ${this.email}\nsalary: ${this.salary}`;
                }
            }
        })('admin', 'admin@php.cn')
        //()相当于执行了一次函数
        console.log(user);
        console.log(user.show());

        user.num = 100;
        console.log(user.num);
    </script>
</body>

</html>
demo4:原生调用JS模块
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模块2</title>
</head>

<body>
    <!-- 原生js不支持模块系统 ,加上type="module" 就可以支持调用了-->
    <script type="module">
        // 模块就是一个js文件
        // 导入模块
        import { user, hello, email } from './m1.js'
    </script>

</body>

</html>
//m1.js
let user = '猪老师';

function hello(name) {
    return 'hello ' + name;
}

let email = '498668472@qq.com';

// 导出数据,不导出无法调用该模块
export { user, hello, email };
Name:
<提交>