Promise 详解

news2024/11/18 5:50:40

Promise 详解

  • 示例
      • 一个抽奖小游戏
          • 原生 JavaScript 实现
          • Promise 实现
      • 读取文件
          • 原生 JavaScript 实现
          • Promise 实现
  • Promise 对象
      • Promise 对象的状态
      • Promise 对象的创建
          • Promise 对象的状态的改变
            • pending 转换为 fulfilled
            • pending 转换为 rejected
  • 与 Promise 对象相关的 API
      • Promise.then()
      • Promise.catch()
      • Promise.resolve()
          • 验证
      • Promise.reject()
          • 验证
  • 转换为 Promise 对象的规则
      • Promise 对象转换为 Promise 对象
      • 非 Promise 数据转换为 Promise 对象
          • 验证
      • 抛出错误
          • 验证
  • Promise 中的链式调用
      • 链式调用
      • 猜猜看
          • 分析
      • 异常穿透
      • 中断

示例

在进行 Promise 的讲解前,请先通过两个小示例来感受一下 Promise。

一个抽奖小游戏

原生 JavaScript 实现
<!DOCTYPE html>
<html lang="en">
<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>抽奖</title>
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
    <button id="start">Start</button>    

    <script src="./index.js"></script>
</body>
</html>
*{
    /* 消除浏览器样式默认存在的内外边距 */
    margin: 0px;
    padding: 0px;
    box-sizing: border-box;
}


body{
    /* 
    设置 body 元素的最低高度为浏览器可视区域的高度,
    并为该标签设置了 flex 布局。
    */
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}


/* 为按钮设置样式 */
#start{
    width: 130px;
    height: 40px;
    border: 1px solid yellow;
    background-color: red;
    color: #fff;
    font-size: 600;
    font-weight: 700;
    border-radius: 3px;
    /* 为按钮设置过渡动画效果,过渡时间为 1s */
    transition: all 1s;
}


/* 为按钮添加鼠标悬停效果 */
#start:hover{
    cursor: pointer;
    width: 200px;
}
function rand(min, max) {
    // 随机数生成函数
    // 该函数将返回一个位于区间 [min, max) 的随机数(包括 min 但不包括 max)
    return Math.floor(Math.random() * (max - min) + min);
}


// 获取 DOM 元素
const btn = document.querySelector('#start');


// 为 DOM 元素添加点击事件,为模拟抽奖过程中存在的延迟我们的事件调用函数
// 是一个 setTimeout() 函数,我们为这个定时器函数设置了 1s 的延迟。
btn.addEventListener('click', () => {
    setTimeout(() => {
        if(rand(1, 100) > 30){
            alert('恭喜你中奖了!')
        }else{
            alert('很遗憾,请再接再厉!')
        }
    }, 1000)
}
)
Promise 实现

Promise 实现与原生 JavaScript 实现的不同点仅位于 JavaScript 代码部分。

function rand(min, max) {
    // 随机数生成函数
    // 该函数将返回一个位于区间 [min, max) 的随机数(包括 min 但不包括 max)
    return Math.floor(Math.random() * (max - min) + min);
}


// 获取 DOM 元素
const btn = document.querySelector('#start');


// 为 DOM 元素添加点击事件,为模拟抽奖过程中存在的延迟我们的事件调用函数
// 是一个 setTimeout() 函数,我们为这个定时器函数设置了 1s 的延迟。
btn.addEventListener('click', () => {
    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            if(rand(1, 100) > 30){
                resolve() // 成功执行后需要执行的函数,该函数执行后将 Promise 对象的状态设置为 【成功】
            }else{
                reject()  // 成功执行后需要执行的函数,该函数执行后将 Promise 对象的状态设置为 【失败】
            }
        }, 1000)
    })
    
    p.then(() => {
        alert('恭喜你中奖了!')
    }, 
    () => {
        alert('很遗憾,请再接再厉!')
    })  
    // then() 方法中的第一个参数为成功执行时需要调用的函数,第二个参数为失败执行时需要调用的函数
})

读取文件

原生 JavaScript 实现

由于读取文件需要使用 fs 模块,我们需要通过 Node.js 来运行该示例文件。如果你在浏览器中导入该示例文件很可能会在控制台中看到如下错误:

require

让我们看看被读取文件中的内容:

                    《也是微云》
                        胡适
            也是微云,也是微云过后月光明。
            只不见去年的游伴,只没有当日的心情。
            不愿勾起相思,不敢出门望月。
            偏偏月进窗来,害我相思一夜。
// 导入 fs 模块
const fs = require('fs');


fs.readFile('./content.txt', (err, data) => {
    if(err) throw(err);
    // 由于读取的结果为 buffer 对象,所以我们需要通过
    // toString() 函数来将该 buffer 对象转换为字符串。
    console.log(data.toString())
})

在终端中 cd 进入该示例文件后,使用如下命令运行该文件(需先安装 Node.js):

node index.js
Promise 实现
const fs = require('fs');


fs.readFile('../content.txt', (err, data) => {
    const p = new Promise((resolve, reject) => {
        if(err) reject(err);
        resolve(data);
    })

    p.then((value) => {
        console.log(value.toString())
    },
    (reason) => {
        throw(reason)
    }
    )
})

同样,执行该文件需要在终端使用 cd 命令切换到到文件所在的路径后使用如下命令(需要先安装并配置 Node.js):

node index.js

Promise 对象

Promise 对象的状态

Promise 对象代表一个异步操作,该对象存在三种状态,对象的状态不受外界影响。对象的状态仅被异步操作的结果影响,任何其他操作都无法改变这个状态,这也是 Promise 这个名字的由来。

Promise 对象的状态由其 PromiseState 属性进行记录。

状态值描述
pending初始状态,执行的操作既没有被拒绝也没有被同意。
rejected已拒绝,执行操作失败。
fulfilled已同意,执行操作成功。

状态的变换仅存在两种可能:

  1. pending 变为 rejected
  2. pending 变为 fulfilled

注:

  1. 状态的转换仅能发生一次。状态由 pending 转换为 rejected 或 fulfilled 后将无法再发生改变。
  2. 对象的状态将决定后续调用的回调函数具体为哪一个。
  3. 若 Promise 对象的状态由 pending 转换为 rejected 而你没有对此进行捕获(设置 rejected 状态下需要执行的回调函数),则浏览器将抛出错误。类似于这样:
    打印结果
    可以通过使用 Promise.catch() 方法来对该状态进行捕获。

Promise 对象的创建

Promise 对象可以通过 new 来调用 Promise() 构造函数来进行创建。

const p = new Promise((resolve, reject) => {
	if(1==1):
		resolve()
	else: 
		reject()
})

其中:

  1. 构造函数 Promise() 接收一个参数,你可以通过使用该参数提供一个函数来指定需要执行的 执行器函数
    执行器函数的第一个参数所对应的函数用于将 Promise 对象的状态由 pending 转换为 fulfilled。而第二个参数所对应的函数用于将 Promise 对象由 pending 转换为 rejected
  2. resolve()reject() 函数的调用仅改变创建的 PromisePromiseState 属性的值,并不会中止执行器函数的运行。
    在下面的这个例子中,Win 将被成功打印:
<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    <script>
        const p = new Promise((resolve, reject) => {
	        if(1==1){
		        resolve()
                console.log('Win')
            }
	        else{
                reject()
            }
        })
    </script>
</body>
</html>
  1. Promise 对象创建的过程中会调用作为参数传递给 Promise 构造函数的函数,所以应该在合适的地方(比如某个事件调用函数中)创建 Promise 对象。
Promise 对象的状态的改变
pending 转换为 fulfilled

通过调用提供给 Promise 构造函数的函数的第一个参数对应的函数 resolve() 即可将创建的 Promise 对象的状态由 pending 转换为 fulfilled

pending 转换为 rejected
  1. 通过调用提供给 Promise 构造函数的函数的第二个参数对应的函数 reject() 即可将创建的 Promise 对象的状态由 pending 转换为 rejected
  2. 通过在提供给 Promise 构造函数的函数中使用关键字 throw 抛出错误也可以将 Promise 对象的状态属性 PromiseStatepending 转换为 rejected
    举个栗子:
<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p = new Promise((resolve, reject) => {
	        if(1==1){
                throw 'Error';
            }
        })

        console.log(p)
    </script>
</body>
</html>

打印结果:

打印结果

与 Promise 对象相关的 API

Promise.then()

Promise.then() 接收两个参数,其中第一个参数为 Promise 对象的状态为 fulfilled 时执行的回调函数;第二个参数为 Promise 对象的状态为 rejected 时执行的回调函数。

Promise.catch()

Promise.catch() 与 Promise.then() 类似,Promise.catch() 仅接收一个参数,你可以为该参数提供一个实参(函数),用于指定 Promise 对象的状态为 rejected 时执行的调用函数。

Promise.resolve()

Promise.resolve() 方法用于将基本数据类型或其他引用数据类型转换为 Promise 对象。对于 Promise.resolve() ,存在如下关系:

Promise.resolve('RedHeart');

// 等价于

new Promise((resolve) => {resolve('RedHeart')});
验证
<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p1 = Promise.resolve('RedHeart');
        const p2 = new Promise((resolve) => {resolve('RedHeart')});

        console.log(p1);
        console.log(p2);
    </script>
</body>
</html>

打印结果:

打印结果

Promise.reject()

Promise.reject() 方法用于将基本数据类型或其他引用数据类型转换为 Promise 对象。对于 Promise.reject(), 存在如下关系:

Promise.reject('RedHeart');

// 等价于

new Promise((resolve, reject) => {reject('RedHeart')});
验证
<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p1 = Promise.reject('RedHeart');
        const p2 =new Promise((resolve, reject) => {reject('RedHeart')});
        
        console.log(p1);
        console.log(p2)
    </script>
</body>
</html>

打印结果:

打印结果

转换为 Promise 对象的规则

在使用 Promise.then()、Promise.reject() 等函数时可能会将其他数据转换为 Promise 对象,转换过程中将遵循一定的转换规则。

Promise 对象转换为 Promise 对象

如果被转换的 Promise 对象的状态结果为 rejected ,则转换后的 Promise 对象的状态也将为 rejected;如果被转换的 Promise 对象的状态结果为 fulfilled ,则转换后的 Promise 对象的状态也将为 fulfilled

<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p1 = Promise.resolve(new Promise((resolve, reject) => {
            resolve('RedHeart')
        }));

        const p2 = Promise.resolve(new Promise((resolve, reject) => {
            reject('RedHeart')
        }));

        
        console.log(p1);
        console.log(p2)
    </script>
</body>
</html>

打印结果:
打印结果
注:
若 Promise.then() 的调用函数中使用 retrun 返回了一个 Promise 对象,则 Promise.then() 返回的 Promise 对象依据此类情况(Promise 对象转换为 Promise 对象)进行判断。

非 Promise 数据转换为 Promise 对象

非 Promise 对象转换为 Promise 对象后的 Promise 对象的结果存在以下情况:

  1. 经 Promise.resolve() 转换后得到的 Promise 对象的状态为 fulfilled;而经 Promise.reject() 转换后得到的 Promise 对象的状态为 rejected。Promise.resolve() 及 Promise.reject() 得到的 Promise 对象的 PromiseResult 属性值均为提供给他们各自的参数。
  2. Promise.then() 及 Promise.catch() 的转换结果均由其调用的回调函数来决定。但对于非 Promise 数据转换为 Promise 对象这种情况,得到的 Promise 对象的状态都将为 fulfilled,其 PromiseResult 属性的值则由其调用的回调函数的返回值决定。
验证
<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p1 = Promise.resolve('RedHeart');
        const p2 = Promise.reject('RedHeart');
        var p3 = new Promise((resolve, reject) => {
            resolve('RedHeart')
        });
        var p4 = new Promise((resolve, reject) => {
            reject('RedHeart')
        });

        p3 = p3.then((value) => {
            return 'p3'
        });

        p4 = p4.catch((reason) => {
            return 'p4'
        });

        console.log(p1);
        console.log(p2);
        console.log(p3);
        console.log(p4);
    </script>
</body>
</html>

打印结果:

打印结果

抛出错误

  1. 经 Promise.resolve() 转换后得到的 Promise 对象的状态为 fulfilled;而经 Promise.reject() 转换后得到的 Promise 对象的状态为 rejected。Promise.resolve() 及 Promise.reject() 得到的 Promise 对象的 PromiseResult 属性值均为提供给他们各自的参数。
  2. 若回调函数中抛出错误,则 Promise.then() 及 Promise.catch() 产生的 Promise 对象的状态均为 rejected。而他们的 PromiseState 属性值为调用函数中抛出错误时提供的信息。
验证
<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p1 = Promise.resolve(() => {
            throw 'Error'
        });
        const p2 = Promise.reject(() => {
            throw 'Error'
        });
        
        var p3 = new Promise((resolve, reject) => {
            resolve()
        });
        var p4 = new Promise((resolve, reject) => {
            reject()
        });

        p3 = p3.then(() => {
            throw 'Error'
        });
        p4 = p4.catch(() => {
            throw 'Error'
        });


        console.log(p1);
        console.log(p2);
        console.log(p3);
        console.log(p4);
    </script>
</body>
</html>

打印结果:
执行结果

Promise 中的链式调用

链式调用

由于 Promise.then() 及 Promise.catch() 等函数的返回结果仍旧为 Promise 对象,所以我们可以像这样去使用 Promise.then() 的返回结果:

<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p = new Promise((resolve, reject) => {
            resolve()
        });

        p.then(() => {
            console.log('1')
        }).then(() => {
            console.log('2')
        }).then(() => {
            console.log('3')
        })
    </script>
</body>
</html>

打印结果:
打印结果z

注:

  1. 链式调用过程中的调用结果(由得到的 Promise 对象的 PromiseStatePromiseResult 属性决定)需要结合前面讲到的 转换为 Promise 对象的规则 来进行判断。

猜猜看

请观察如下代码并猜测最后两个打印语句的打印结果。

<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK')
            }, 1000)
        });

        p.then(value => {
            return new Promise((resolve, reject) => {
                resolve('Win')
            })
        }).then(value => {
            console.log(value)
        }).then(value => {
            console.log(value)
        })
    </script>
</body>
</html>

打印结果:

Win
undefined

分析
  1. 第一个 Promise.then()
    由于第一个 Promise.then() 的返回值为一个 Promise 对象,所以我们需要先判断这个 Promise 对象的 PromiseStatePromiseResult 的值,这两个属性对应的值分别为 fulfilledWin。因此第一个 Promise.then() 返回的 Promise 对象的 PromiseStatePromiseResult 的值分别为 fulfilledWin
  2. 第二个 Promise.then()
    由于第一个 Promise.then() 返回的 Promise 对象的 PromiseStatePromiseResult 的值分别为 fulfilledWin。因此传递给第二个 Promise.then() 的 value 对应的值为 Winfulfilled 决定能不能调用第二个 Promise.then() 函数,如果第一个 Promise.then() 的 PromiseState 对应的值为 rejected,则第二个 Promise.then() 将不会被调用。
  3. 第三个 Promise.then()
    由于第二个 Promise.then() 发生了 非 Promise 数据转换为 Promise 对象,所以第二个 Promise.then() 的结果为 Promise 对象,该对象的PromiseStatePromiseResult 的值分别为 fulfilledundefined

异常穿透

我们可以在链式调用的最后一环添加一个 Promise.catch() 函数以应对可能产生的 rejected 状态的 Promise 对象。就像这样:

<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK')
            }, 1000)
        });

        p.then(value => {
            return new Promise((resolve, reject) => {
                reject()
            })
        }).then(value => {
            console.log(value)
        }).then(value => {
            console.log(value)
        }).catch(reason => {
            console.log('Lose')
        })
    </script>
</body>
</html>

打印结果:

Lose

中断

对于下面的代码,如果你希望打印的结果为:

1
2

而不是:

1
2
3

你该怎么做?

<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p = new Promise((resolve, reject) => {
            resolve()
        });

        p.then(() => {
            console.log(1)
        }).then(() => {
            console.log(2)
        }).then(() => {
            console.log(3)
        })
    </script>
</body>
</html>

我们可以尝试在第二个 Promise.then() 中的调用函数中返回一个特定状态(在这个例子中需要的 Promise 对象的状态应该为 pendingrejected)的 Promise 对象来中断链式调用。

<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p = new Promise((resolve, reject) => {
            resolve()
        });

        p.then(() => {
            console.log(1)
        }).then(() => {
            console.log(2)
            return new Promise((resolve, reject) => {
                reject()
            })
        }).then(() => {
            console.log(3)
        })
    </script>
</body>
</html>

打印结果:

打印结果

使用如下代码也可以在适当的时机中断链式调用:

<!DOCTYPE html>
<html lang="en">
<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>Demo</title>
</head>
<body>
    
    <script>
        const p = new Promise((resolve, reject) => {
            resolve()
        });

        p.then(() => {
            console.log(1)
        }).then(() => {
            console.log(2)
            return new Promise(() => {})
        }).then(() => {
            console.log(3)
        })
    </script>
</body>
</html>

打印结果:

1
2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/163931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux---gdb调试方法

1. 背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g 选项2. gdb调试 进入/退出调试&#xff1a; list/l 行号&#xff1a;显…

佳能2420报错代码E000007-0000

应该是定影的问题&#xff0c;先试一下清零&#xff0c;如果还是出现这个问题&#xff0c;不是电压就是应该换定影了。&#xff08;包含&#xff1a;轴套、定影膜、缺硅油了【定影膜硅油、润滑脂】&#xff09; 维修模式菜单&#xff1a; CLEAR > ENGIN > ERRCLR &…

交大博士学长:研究生计算机专业的方向选择!

Datawhale干货 作者&#xff1a;一辈闲&#xff0c;上海交大博士&#xff0c;Datawhale邀约作者作者知乎&#xff1a;https://www.zhihu.com/people/yi-bei-xian-16目前计算机专业的研究方向主要分为四个大方向分别是&#xff1a;AI&#xff08;人工智能&#xff09;、Systems&…

常微分方程组解稳定性的分析

文章未完相空间的绘制我们随机选一个方程,随机选的,不是有数学手册吗,一般来说考题不可能出数学手册上的例子import scipy.integrate as si import matplotlib.pyplot as plt import numpy as np## dx/dt x**2-y**2xy ## dy/dt x*y**2 - x**2*yf lambda x,y:x**2-y**2xy g…

HashMap、HashTable和ConcurrentHashMap的区别

HashMap是线程不安全的&#xff0c;HashTable和ConcurrentHashMap是线程安全的。HashTable的实现线程安全的方式是&#xff1a;将所有的方法都加上锁&#xff0c;也就相当于对this加锁&#xff0c;此时&#xff0c;无论访问HashTable的任何一个元素都会加锁操作&#xff0c;在多…

ESP32设备驱动-MMA8451加速度计驱动

MMA8451加速度计驱动 1、MMA8451介绍 MMA8451 是一款具有 14 位分辨率的低功耗加速度计,具有灵活用户可编程选项的嵌入式功能,可配置为两个中断引脚。嵌入式中断功能可实现整体节能,从而使主机处理器免于连续轮询数据访问低通滤波数据和高通滤波数据,最大限度地减少颠簸检…

DockerCompose安装卸载、文件语法格式

DockerCompose安装卸载、文件语法格式 一、DockerCompose的概念和作用 1.1 相关概念 DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;不需要我们手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如…

【蓝桥杯】时间显示(省赛)Java

【问题描述】 小蓝要和朋友合作开发一个时间显示的网站。在服务器上&#xff0c;朋友已经获取了当前的时间&#xff0c;用一个整数表示&#xff0c;值为从1970年1月1日O0:00:00到当前时刻经过的毫秒数。 现在&#xff0c;小蓝要在客户端显示出这个时间。小蓝不用显示出年月日&a…

IIC通信协议

数据有效性 IC由两条线组成&#xff0c;一条双向串行数据线SDA&#xff0c;一条串行时钟线SCL。 SDA线上的数据必须在时钟的高电平周期保持稳定&#xff0c;数据线的高或低电平状态只有在 SCL 线的时钟信号是低电平时才能改变。 换言之&#xff0c; SCL为高电平时表示有效数据…

Crack:结构分析和设计软件:Cross Section Analysis-Design

Cross Section Analysis & Design &#xff08;美国、欧洲、亚洲和澳大利亚最受好评的结构软件&#xff09;是一款功能强大的应用程序&#xff0c;可以执行各种横截面计算&#xff0c;包括钢筋混凝土截面的设计&#xff08;钢筋计算器&#xff09;。所提供的横截面可以是简…

Python之argparse模块的使用

我们在写一个成熟的Python项目时候&#xff0c;需要传入若干指定的参数。而不是写死在程序里&#xff0c;这个时候就要用到argparse模块。argparse 是 Python 内置的一个用于命令项选项与参数解析的模块&#xff0c;通过在程序中定义好我们需要的参数&#xff0c;argparse 将会…

【FPGA笔记系列3】assign语句和if-esle语句

结构化建模 前面几节中采用的方法称为结构化建模。 assign语法(数据流建模方式) assign语句仅能描述组合逻辑电路,没有涉及时钟、触发器等! 五人投票电路(由于CGD100板子原因,需修改逻辑使按下点亮,弹起熄灭) 因为板子当key按下时为低电平,弹起时为高电平;led高电平点…

MyBatis查询接收数据 批量删除

MyBatis查询接收数据 批量删除查询出的数据只有一条通过实体类对象接收通过List集合接收通过map集合接收查询出的数据有多条通过list集合接收通过map类型的list集合接收MapKey注解模糊查询批量删除${}和#{}的区别查询出的数据只有一条 通过实体类对象接收 mapper接口代码: 映射…

Lr 12 ACR 15:传统蒙版工具

在 Lr 或 ACR 中&#xff0c;可以用各种不同的方式创建或添加蒙版。其中主题、天空、背景、对象及人物&#xff08;若照片上有&#xff09;都是由 AI 技术提供支持。画笔、线性渐变、径向渐变、范围等是传统的蒙版工具。画笔Brush手动绘制要选择的区域。创建一个画笔&#xff1…

C#,图像二值化(24)——局部阈值算法的NiBlack算法及源程序

1、局部阈值算法的NiBlack算法摘要-医学图像的处理最为复杂人和计算机。磁性捐赠的脑组织共振成像&#xff08;MRI&#xff09;在许多领域是非常重要的问题例如手术和治疗。最常见的分割图像的最简单方法是使用阈值。在这项工作中&#xff0c;我们提出了一个有效的实现阈值&…

SpringBoot整合Mybatis和MybatisPlus

目录 一、整合MyBatis操作 1、配置模式 2、注解模式 3、混合模式 二、整合 MyBatis-Plus 完成CRUD 1、什么是MyBatis-Plus 2、整合MyBatis-Plus 3、CRUD功能 一、整合MyBatis操作 官网&#xff1a;MyBatis GitHub SpringBoot官方的Starter&#xff1a;spring-boot-st…

兼容东西,贯通南北:超聚变的“四水归堂”

四水归堂&#xff0c;是中国建筑艺术中的一种独特形式。这种形式下&#xff0c;由四面房屋围出一个天井&#xff0c;房屋内侧坡向天井内倾斜&#xff0c;下雨时雨水会从东西南北四方流入天井&#xff0c;从而起到收集水源&#xff0c;防涝护屋的作用&#xff0c;寓意水聚天心&a…

每日一问-ChapGPT-20230114-关于小年

文章目录每日一问-ChapGPT系列起因每日一问-ChapGPT-20230114-关于小年腊月每天都做些什么的歌谣为什么现在的年味淡了很多&#xff0c;感觉不到过年为什么春节放假要调休&#xff0c;不能多放几天吗说说现在世界上极端气候&#xff0c;以及多少年后&#xff0c;地球存在不适宜…

Asp.Net项目的部署到Linux中(Linux + Jexus+Nginx )

因为老项目用的Asp.Net Web API技术开发部署到Window系统上&#xff0c;而新项目用的是.Net Core部署到Ubuntu系统中&#xff0c;所以在管理切换上有些不便。于是决定将老项目的测试服部署到Ubuntu中&#xff0c;试试水。 一、简述 要实现Asp.Net项目部署到Linux中&#xff0c…

C语言入门教程|| C语言 程序结构|| C语言 基本语法

在我们学习 C 语言的基本构建块之前&#xff0c;让我们先来看看一个最小的 C 程序结构&#xff0c;在接下来的章节中可以以此作为参考。 C 程序主要包括以下部分&#xff1a; 预处理器指令函数变量语句 & 表达式注释 让我们看一段简单的代码&#xff0c;可以输出单词 &qu…