Promise用法

一. 前后端交互模式

1.1 接口调用方式

  • 原生 ajax
  • 基于 jQuery 的ajax
  • fetch
  • axios

在这里插入图片描述

1.2 URL 地址格式

1. 传统形式的 URL

  • 格式:schema://host:port/path?query#fragment

    ①schema:协议。例如http、https、ftp等

    ②host:域名或者IP地址

    ③port:端口, http默认端口80,可以省略

    ④path:路径, 例如/abc/a/b/c

    ⑤query :查询参数,例如 uname=lisi&age=12

    ⑥fragment :锚点(哈希Hash),用于定位页面的某个位置

  • 符合规则的URL

    ①http://www.duanxx.cn

    ②http://www.duanxx.cn/java/web

    ③http://www.duanxx.cn/java/web?flag=1

    ④http://www.duanxx.cn/java/web?flag=1#function

2. Restful 形式的 URL

  • HTTP请求方式

    ① GET 查询

    ② POST 添加

    ③ PUT 修改

    ④ DELETE 删除

  • 符合规则的URL地址

    ① http://www.hello.com/books GET

    ② http://www.hello.com/books POST

    ③ http://www.hello.com/books/123 PUT

    ④ http://www.hello.com/books/123 DELETE

二. Promise 用法

2.1 异步调用

  • 异步效果分析

    ①定时任务

    ②Ajax

    ③事件函数

  • 多次异步调用的依赖分析

    ① 多次异步调用的结果顺序不确定

    ② 异步调用结果如果存在依赖需要嵌套

缺点

形成 回调地狱 。

$.ajax({
  success: function(data){
    if(data.status == 200){
      $.ajax({
        success: function(data){
          if(data.status == 200){
            $.ajax({
              success: function(data){
                if(data.status == 200){}
              }
            });
          }
        }
      });
    }
  }
});

2.2 Promise 概述

Promise 是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。

使用 Promise 主要有以下好处:

  • 可以避免多层异步调用嵌套问题(回调地狱)
  • Promise 对象提供了简洁的API,使得控制异步操作更加容易

官方描述:点击这里 ——> Promise

2.3 Promise 基本用法

  • 实例化 Promise 对象,构造函数中传递函数,该函数中用于处理异步任务
  • resolvereject 两个参数用于处理成功和失败两种情况,并通过 p.then 获取处理结果

语法结构

 var p = new Promise(function(resolve, reject){
   // 成功时调用 resolve()
   // 失败时调用 reject()
 });
 p.then(funciton(ret){
     // 从resolve得到正常结果
  }, function(ret){
     // 从reject得到错误信息
  });

案例

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>promise基本用法</title>
</head>

<body>
    <script type="text/javascript">
        var p = new Promise(function(resolve, reject) {
            // 这里用于实现异步任务
            setTimeout(function() {
                var flag = false;
                if (flag) {
                    // 正常情况
                    resolve("Hello Promise");
                } else {
                    reject('Error ! ! !');
                }
            }, 1000);
        });
        p.then(function(data) {
            console.log(data);
        }, function(info) {
            console.log(info);
        });
    </script>
</body>

</html>

2.4 基于Promise处理Ajax请求

1. 处理原生Ajax

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise处理原生Ajax请求</title>
</head>

<body>
    <script type="text/javascript">
        function queryData(url) {
            var p = new Promise(function(resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function() {
                    if (xhr.readyState != 4) return;
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // 处理正常情况
                        resolve(xhr.responseText);
                    } else {
                        reject('服务器错误!');
                    }
                };
                xhr.open('get', url);
                xhr.send(null);
            });
            return p;
        }
		
        // 单次调用
        // queryData('http://localhost:3000/data')
        //     .then(function(data) {
        //         console.log(data);
        //     }, function(info) {
        //         console.log(info);
        //     });
        // 多次调用
        queryData('http://localhost:3000/data')
            .then(function(data) {
                console.log(data);
                return queryData('http://localhost:3000/data1');
            })
            .then(function(data) {
                console.log(data);
                return queryData('http://localhost:3000/data2');
            })
            .then(function(data) {
                console.log(data);
            });
    </script>
</body>

</html>

2.5 then参数中的函数返回值

1. 返回 Promise 实例对象

  • 返回的该实例对象会调用下一个 then

2. 返回普通值

  • 返回的普通值会直接传递给下一个 then,通过 then 参数中函数的参数接收该值
  • 如果上一个then返回普通值,它会默认生成一个Promise实例对象,这是为了保证继续链式操作

案例:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>then参数中的返回值</title>
</head>

<body>
    <script type="text/javascript">
        function queryData(url) {
            return new Promise(function(resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function() {
                    if (xhr.readyState != 4) return;
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // 处理正常情况
                        resolve(xhr.responseText);
                    } else {
                        reject('服务器错误!');
                    }
                };
                xhr.open('get', url);
                xhr.send(null);
            });
        }

        queryData('http://localhost:3000/data')
            .then(function(data) {
                queryData('http://localhost:3000/data1');
            })
            .then(function(data) {
                return new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        resolve(123);
                    }, 1000);
                });
            })
            .then(function(data) {
            	// console.log(data) 	// 结果:123
                return 'Hello Little Dragon Boy!'
            })
            .then(function(data) {
                console.log(data);
            })
    </script>
</body>

</html>

2.6 Promise常用的API

1. 实例方法

  • p.then() 得到异步任务的正确结果
  • p.catch() 获取异常信息
  • p.finally() 成功与否都会执行(尚且不是正式标准)

案例

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise中常用API</title>
</head>

<body>
    <script type="text/javascript">
        function foo() {
            return new Promise(function(resolve, reject) {
                setTimeout(function() {
                    resolve('Good Promise!');
                    // reject('Error ! ! !');
                }, 100);
            });
        };

        foo()
            .then(function(data) {
                console.log(data);
            })
            .catch(function(data) {
                console.log(data);
            })
            .finally(function() {
                console.log('finished!');
            });
    </script>
</body>

</html>

2. 对象方法

  • Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果
  • Promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>常用API对象方法</title>
</head>

<body>
    <script type="text/javascript">
        function queryData(url) {
            return new Promise(function(resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function() {
                    if (xhr.readyState != 4) return;
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        // 处理正常情况
                        resolve(xhr.responseText);
                    } else {
                        reject('服务器错误!');
                    }
                };
                xhr.open('get', url);
                xhr.send(null);
            });
        };

        var p1 = queryData('http://localhost:3000/a1');
        var p2 = queryData('http://localhost:3000/a2');
        var p3 = queryData('http://localhost:3000/a3');
        // Promise.all([p1, p2, p3]).then(function(result) {
        //     console.log(result);
        // });
        Promise.race([p1, p2, p3]).then(function(result) {
            console.log(result);
        });
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值