Promise:工作流程、常见API、使用方法、手撕Promise、async/await

news2024/10/5 14:20:21

Promise和axios

  • 一、Promise的常见骚操作
    • 0.初体验
    • 1.使用Promise封装原生AJAX
    • 2.Promise实例对象的两个属性
      • (1)状态属性`PromiseState`
      • (2)结果值属性`PromiseResult`
    • 3.Promise的工作流程
    • 4.Promise的API
      • (1).then和.catch
      • (2)Promise.resolve(参数)
      • (3)Promise.reject(参数)
      • (4)Promise.all([参数1,参数2...])
      • (5)Promise.race([参数1,参数2...])
  • 二、一些关键问题
    • 1.改变对象状态的方式
    • 2.能否执行多个回调
    • 3.改变状态和指定回调的顺序
    • 4.then/catch方法返回结果由什么决定
    • 5.串联多个任务(链式调用)
    • 6.异常穿透
    • 7.中断Promise链条
  • 三、手撕Promise
    • 1.搭建整体结构
    • 2.resolve和reject的实现
    • 3.throw抛出错误改变状态
    • 4.状态一旦改变就不能再变
    • 5.then方法的初步封装
    • 5.异步任务回调的执行
    • 6.执行多个then的回调

Promise指定回调函数的方式更加灵活,且支持链式调用,可以解决回调地狱的问题。

回调地狱:回调函数嵌套调用,外部回调执行结果是内部函数执行的条件,不便于阅读且不便于异常处理,解决方式就是promise(或async/await)

一、Promise的常见骚操作

0.初体验

先来看一个案例:抽奖

// 生成随机数
function rand(m,n) {
    return Math.ceil(Math.random() * (n-m+1) + m-1);
}

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        let n = rand(1, 100);
        if (n <= 30) {
            resolve(n); //把Promise对象的状态从未完成=>成功
        } else {
            reject(n);  //把Promise对象的状态从未完成=>失败
        }
    }, 1000);
});

Promise接收两个参数,分别是resolvereject,这两个参数都是函数类型
我们可以用.then来指定成功或失败的回调。(第一个回调是成功的回调,参数为调用resolve时传过来的参数,第二个回调是失败的回调,参数为调用reject传过来的参数)

p.then((res)=>{
    console.log('异步成功:',res);  //异步成功:12
},(error)=> {
    console.log('异步失败:',error);  //异步失败:66
})

下面这个用catch写法和上面是等价的:

p.then((res)=>{
    console.log('异步成功:',res); //异步成功:12
}).catch((error)=> {
    console.log('异步失败:',error);  //异步失败:66
})

1.使用Promise封装原生AJAX

//定义一个方法,发送ajax请求
function sendAjax() {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.responseType = 'json';  //指定返回结果格式
        xhr.open('GET', 'https://ku.qingnian8.com/dataApi/news/navlist.php');
        xhr.send();
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve(xhr.response);
                } else {
                    reject(xhr.status);
                }
            }
        }
    });
}

//调用方法返回的是promise对象,直接.then就欧了
sendAjax().then(res => {
    console.log(res);
}).catch(err => {
    console.log(err);
})

2.Promise实例对象的两个属性

回到前边的抽奖案例,如果我们打印一下p,可以看到两个属性:

在这里插入图片描述

上面是成功,下面是失败

在这里插入图片描述
是的,这两个属性分别是状态属性PromiseState和结果值属性PromiseResult

(1)状态属性PromiseState

有三个值,分别是pendingfulfilledrejected
promise状态的改变只有两种,分别是:

1、pending => fulfilled
2、pending => rejected

而且一个promise对象只会改变一次,改变之后就不会再变

(2)结果值属性PromiseResult

这个属性保存的是异步成功或失败的结果
无论成功还是失败,都只有一个结果数据
这个结果是通过resolvereject这两个函数参数,保存在PromiseResult属性中的
成功穿过去的参数一般叫value,失败的参数一般叫reason(当然我习惯写res和err)

3.Promise的工作流程

在这里插入图片描述

4.Promise的API

Promise对象中的函数是同步调用的,下面的代码依次输出:我同步执行,奥里给

const p = new Promise((resolve, reject) => {
	//这个函数是同步调用的
	console.log('我同步执行');
});
console.log('奥里给');

(1).then和.catch

这部分上面讲过了,可以去看看0.初体验部分

(2)Promise.resolve(参数)

这个方法可以返回一个Promise对象,注意:

1、如果传入的参数是一个非Promise类型,那么返回一个成功的Promise对象,参数也就是成功的回调中的value值

const p1 = Promise.resolve(521);
console.log(p1);

在这里插入图片描述

2、如果传入的参数是一个Promise类型,那么返回的结果取决于传入的Promise的结果
如果结果为resolve,那么返回成功的Promise,值就是里面调用resolve的参数成功

const p2 = Promise.resolve(new Promise((resolve,reject) => {
    resolve('成功');
}))
console.log(p2);

在这里插入图片描述

3、如果结果为reject,那么返回失败的Promise,值就是里面调用reject的参数失败

const p2 = Promise.resolve(new Promise((resolve,reject) => {
    // resolve('成功');
    reject('失败');
}))
console.log(p2);

在这里插入图片描述

不想让控制台报错,只需要用catch捕获一下:

const p2 = Promise.resolve(new Promise((resolve,reject) => {
    // resolve('成功');
    reject('失败');
}))
console.log(p2);
p2.catch(err => console.log(err));

在这里插入图片描述

(3)Promise.reject(参数)

不管传入的参数是什么,都会返回一个失败的Promise对象,传入的参数是什么,结果就是什么(若参数是Promise对象,那么结果值也是Promise对象)。

1、如果传的是非Promise,返回的是失败的Promise,结果就是传的值:

const p3 = Promise.reject(520);
console.log(p3);

在这里插入图片描述

2、如果传的是成功的Promise,返回的是失败的Promise对象,该对象的结果值PromiseResult是成功的Promise对象:

const p4 = Promise.reject(new Promise((resolve,reject)=>{
    resolve('OK');
    // reject('错误');
}))
console.log(p4);

在这里插入图片描述

3、如果传的是失败的Promise,返回的是失败的Promise对象,该对象的结果值PromiseResult是失败的Promise对象:

const p4 = Promise.reject(new Promise((resolve,reject)=>{
    // resolve('OK');
    reject('错误');
}))
console.log(p4);

在这里插入图片描述

(4)Promise.all([参数1,参数2…])

1、返回结果是一个Promise对象,该方法参数是一个Promise对象构成的数组,只有所有的Promise成功,返回的状态才是成功,值为一个成功结果值构成的数组

const p1 = new Promise((resolve,reject)=> {
    resolve('OK');
})
const p2 = Promise.resolve('成功');
const p3 = Promise.resolve('欧了');
const result = Promise.all([p1,p2,p3]);
console.log(result);

在这里插入图片描述

2、如果有一个失败,那么返回的Promise状态为失败,结果值为第一个失败的结果值

const p1 = new Promise((resolve,reject)=> {
    resolve('OK');
})
const p2 = Promise.reject('失败');
const p3 = Promise.reject('完蛋');
const result = Promise.all([p1,p2,p3]);
console.log(result);

在这里插入图片描述
这玩意儿应用场景还是蛮多的,比如同时去改数据库的两个表,两个表都改完了,再使用.then的回调提示用户修改成功。

(5)Promise.race([参数1,参数2…])

参数是多个Promise对象构成的数组,这个race本身是赛跑的意思,所以这个API的作用就是:多个异步操作,哪个先返回结果(先完成),那么调用这个API返回的就是谁。

比如下面这段代码,p1加了定时器,那么p2先返回结果,所以result返回的就是一个失败的Promise,值是p2的结果值

const p1 = new Promise((resolve,reject)=> {
    setTimeout(() => {
        resolve('OK');
    }, 1000);
})
const p2 = Promise.reject('失败');
const p3 = Promise.reject('完蛋');
const result = Promise.race([p1,p2,p3]);
console.log(result);

在这里插入图片描述

二、一些关键问题

1.改变对象状态的方式

有三种方式可以改变Promise对象的状态,分别是1.resolve函数 2.reject函数 3.抛出错误

const p = new Promise((resolve,reject)=> {
    //1.resolve函数
    resolve('成功'); //pending => resolved/fulfilled
    //2.reject函数
    reject('失败'); //pending => rejected
    //3.抛出错误
    throw '出问题了!';  //pending => rejected
})
console.log(p);

2.能否执行多个回调

只要Promise对象的状态改变,那么对应的回调不管有几个,都会执行

const p = new Promise((resolve,reject)=> {
    resolve('DJ');
})

//只要p状态改变为resolved,下面三个回调都会执行
p.then(res=>console.log(res));
p.then(res=>alert(res));
p.then(res=>console.log(res,'drop the beat'));

3.改变状态和指定回调的顺序

有两种情况:
1、若状态改变为同步,那么就是改变状态 => 指定回调 => 执行回调

const p = new Promise((resolve,reject)=> {
     resolve('DJ');
})
p.then(res=>console.log(res));

2、若状态改变为异步,那么就是指定回调 => 改变状态 => 执行回调

const p = new Promise((resolve,reject)=> {
    setTimeout(()=>{
        resolve('DJ');
    },1000)
})
p.then(res=>console.log(res));

记住,执行回调永远在状态改变之后,执行回调和指定回调不是一个概念。指定回调是执行then方法而不是执行then里的嘎达们

4.then/catch方法返回结果由什么决定

调用then(或catch)方法返回的还是Promise对象,返回的这个Promise的状态和结果取决于then中回调的返回值。

1、如果返回非Promise,那么结果为成功的Promise对象,值就是返回值。(这里如果不写返回值,返回的也是成功的Promise,因为不写return,返回的是undefinedundefined也是非Promise类型的数据)
2、抛出错误,那么结果为失败的Promise对象,值就是抛出的值
3、返回一个Promise对象,那么结果取决于该Promise的状态

不管p的状态是成功还是失败,后面链式调用then(或catch)返回的结果,都取决于它里面的回调,就是上面那三个情况

const p = new Promise((resolve,reject)=> {
    resolve('成功');
})
const result = p.then(res => {
    //1.返回非Promise,那么结果为成功的Promise对象,值就是返回值
    //(不写return返回undefined)
    return 521; //result结果为fulfilled、521
    //2.抛出错误,那么结果为失败的Promise对象,值就是抛出的值
    throw '出了问题';  //result结果为rejected、出了问题
    //3.返回一个Promise,那么结果取决于该Promise的状态和值
    return new Promise((resolve,reject)=> {
        // resolve('OK');
        reject('ERROR');
    })
}, error => {
    // return 521;   //返回成功的Promise
    // throw '出了问题';  //返回失败的Promise
    return new Promise((resolve,reject)=> {
        resolve('OK');  //返回成功的Promise,值为OK
        // reject('ERROR');
    })
})
console.log(result);  //上面代码没注释,这里的结果应根据返回值决定

catch也是一样的规则。

const p = new Promise((resolve,reject)=> {
    resolve('成功');
})
const result = p.catch(err => {
    //return 521;  //返回成功的Promise,值为521
    //throw '出了问题';  //result结果为rejected、出了问题
    return new Promise((resolve,reject)=> {
        // resolve('OK');
        reject('ERROR');
    })
})
console.log(result); //返回失败的Promise,值为ERROR

5.串联多个任务(链式调用)

由于.then/.catch返回的还是Promise,所以可以链式调用,解决回调地狱问题。下一个.then/.catch中的回调的参数res是上一个then的Promise结果值(如果上一个没写返回值,那么上一个返回成功的Promise,值为undefined

const p = new Promise((resolve, reject) => {
    resolve('ok');
})

p.then(res => {
    return new Promise((resolve, reject) => {
        resolve('success');
    })
}).then(res => {
    console.log(res); //success
}).then(res => {
    console.log(res); //undefined
})

6.异常穿透

链式调用,在最后写个.catch(或者.then第一个回调写空,第二个回调捕获错误)可以捕获到前面的第一个错误,如果.then中途出现错误,则依次向下执行,寻找处理错误的回调,直到找到.catch(或某个.then的第二个回调),然后执行该回调。

const p = new Promise((resolve,reject) => {
    resolve('ok');
    // reject('错误!');
})

p.then(res => {
    console.log('111');
}).then(res => {
    console.log('222');
    throw '嗷嗷嗷错误'
}).then(res => {
    console.log('333');
}).catch(err => {
    console.warn(err); //嗷嗷嗷错误
})

7.中断Promise链条

其实我们在.then时,不管上一个Promise结果是什么,所有.then都会依次执行,因为每个.then都有两个回调(第二个回调是捕获错误的回调),比如下面的代码,输出结果是:111,dj,333,第二个.then执行了捕获错误的回调,由于没有返回值,返回一个成功的Promise,值为undefined,所以后面的.then还会继续调用

const p = new Promise((resolve, reject) => {
    resolve('ok');
})

p.then(res => {
    console.log('111');
    throw 'dj';
}).then(res => console.log('222'), err => console.log(err))
    .then(res => console.log('333'), err => console.log(err))

想要中断.then和最后.catch的调用,有且只有一种方式:

返回一个pending状态的Promise

const p = new Promise((resolve, reject) => {
    resolve('ok');
})

p.then(res => {
    console.log('111');
    // throw 'dj';
    return new Promise((resolve,reject)=>{}); //pending
}).then(res => console.log('222'), err => console.log(err))
    .then(res => console.log('333'), err => console.log(err))

上面程序执行结果为:111

三、手撕Promise

1.搭建整体结构

先正常搭一个Promise的使用,只不过这个Promise是从我们自定义的文件中引入的构造函数(或者类,这里用ES5的构造函数写吧)

<!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>手撕Promise</title>
    <script src="./Promise.js"></script>
</head>
<body>
    <script>
        const p = new Promise((resolve,reject)=>{
            resolve('ok');
        })

        p.then(res => {
            console.log(res);
        }, err => {
            console.log(err);
        })
    </script>
</body>
</html>

Promise.js

function Promise(executer) {

}

//1.then方法的封装
Promise.prototype.then = function(onResolved,onRejected) {

}

2.resolve和reject的实现

这里的参数executer是一个函数,且是立即执行的,executer的参数是两个函数,分别是成功和失败的函数,即我们常写的resolve和reject。这两个函数调用做的事情一样:1、改变对象的状态,2、改变对象的结果值

function Promise(executer) {
    this.PromiseState = 'pending';
    this.PromiseResult = undefined;
    //参数executer是一个立即调用的函数
    //且该函数还接收两个参数,分别是两个函数
    const success = (data) => {
        //这是resolve对应的回调
        //1.改变对象的状态:pending=>resolved
        this.PromiseState = 'resolved';
        //2.改变对象的结果值
        this.PromiseResult = data;
    }

    const fail = (data) => {
        //这是reject对应的回调
        //1.改变对象的状态:pending=>resolved
        this.PromiseState = 'rejected';
        //2.改变对象的结果值
        this.PromiseResult = data;
    }

    executer(success, fail);
}

//1.then方法的封装
Promise.prototype.then = function (onResolved, onRejected) {

}

3.throw抛出错误改变状态

如果我们要抛出错误:

const p = new Promise((resolve,reject)=>{
    throw 'error';
})

那么应该在Promise构造函数的立即执行函数executer外层包一个try...catch

try {
    executer(success, fail);
} catch(data) {
    //如果抛出错误,那么就执行下面的代码
    fail(data);
}

这样就可以捕获异常,并改变Promise对象的状态

4.状态一旦改变就不能再变

只需要在成功和失败的回调中加个判断,如果当前状态不是pending,说明状态已经改变了,就不再执行后面的代码。

if(this.PromiseState !== 'pending') return;

5.then方法的初步封装

p.then(res => {
    console.log(res);
}, err => {
    console.log(err);
})

因为then方法有两个回调,成功执行第一个,失败执行第二个,所以只需要加个判断就行了,调用函数传的参数就是Promise构造函数中的结果值属性

Promise.prototype.then = function (onResolved, onRejected) {
    //判断走哪个回调
    if(this.PromiseState === 'resolved') {
        onResolved(this.PromiseResult);
    }
    if(this.PromiseState === 'rejected') {
        onRejected(this.PromiseResult);
    }
}

5.异步任务回调的执行

如果是异步任务,那么根据js代码同步执行特性,会先调用then方法,再改变状态,我们要做到在改变状态后再执行then方法中的回调,怎么办?

const p = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('ok');
    }, 1000);
})

p.then(res => {
    console.log(res);
}, err => {
    console.log(err);
})

如果先调用then方法,那么Promise的状态的pending,所以要加个判断,当状态为pending时,就把两个回调保存到Promise实例的某个属性上

function Promise(executer) {
    this.PromiseState = 'pending';//默认应该是等待
    this.PromiseResult = undefined;
    //定义一个属性来存放then函数的回调
    this.callback = {};
    ......
}

Promise.prototype.then = function (onResolved, onRejected) {
    //判断同步任务下走哪个回调
    if (this.PromiseState === 'resolved') {
        onResolved(this.PromiseResult);
    }
    if (this.PromiseState === 'rejected') {
        onRejected(this.PromiseResult);
    }
    //如果是异步任务(先指定回调再改变状态再执行回调)
    if (this.PromiseState === 'pending') {
        //把回调存到该实例的属性上
        this.callback.onResolved = onResolved;
        this.callback.onRejected = onRejected;
    }
}

这样我们就可以实现,异步任务resolve/reject函数调用导致状态改变后,再执行对应的回调

function Promise(executer) {
	......
	
    const success = (data) => {
        //这是resolve对应的回调
        //状态改变后就不能再变,加个判断
        if (this.PromiseState !== 'pending') return;
        //1.改变对象的状态:pending=>resolved
        this.PromiseState = 'resolved';
        //2.改变对象的结果值
        this.PromiseResult = data;
        //3.如果是异步,要在以上步骤结束后,执行对应的回调
        if(this.callback.onResolved){
            this.callback.onResolved(data);
        }
    }

    const fail = (data) => {
        //这是reject对应的回调
        //状态改变后就不能再变,加个判断
        if (this.PromiseState !== 'pending') return;
        //1.改变对象的状态:pending=>resolved
        this.PromiseState = 'rejected';
        //2.改变对象的结果值
        this.PromiseResult = data;
        //3.如果是异步,要在以上步骤结束后,执行对应的回调
        if(this.callback.onRejected) {
            this.callback.onRejected(data);
        }
    }
	......
}

6.执行多个then的回调

异步任务Promise如果有多个then的回调,那么原Promise中是全部都要执行的,但是我们自己封装的这个,会执行最后一个,原因在于我们调用then方法是往对象中保存回调,这样的话后面then方法的回调会覆盖前面的回调。

const p = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('ok');
    }, 1000);
    // reject('notok');
    // throw 'error';
})

p.then(res => {
    console.log(res);
}, err => {
    console.log(err);
})

p.then(res=>{
    alert(res);
}, err => {
    alert(err);
})

所以这时我们应该修改一下数据结构,把保存到实例上的属性变成数组,每次调用then方法,就把成功和失败的回调以对象的形式push进去

function Promise(executer) {
    ......
    //定义一个属性来存放then函数的回调们
    this.callbacks = [];
}

Promise.prototype.then = function (onResolved, onRejected) {
    ......
    //如果是异步任务(先指定回调再改变状态再执行回调)
    if (this.PromiseState === 'pending') {
        //把回调存到该实例的属性上
        // this.callback.onResolved = onResolved;
        // this.callback.onRejected = onRejected;
        this.callbacks.push({
            onResolved: onResolved,
            onRejected   //简写
        })
    }
}

然后再遍历调用

function Promise(executer) {
    ......
    const success = (data) => {
        //这是resolve对应的回调
        ......
        //3.如果是异步,要在以上步骤结束后,执行对应的回调
        // if(this.callback.onResolved){
            // this.callback.onResolved(data);
        // }
        if(this.callbacks.length != 0) {
            this.callbacks.forEach(item => {
                item.onResolved(data);
            })
        }
    }

    const fail = (data) => {
        //这是reject对应的回调
        ......
        //3.如果是异步,要在以上步骤结束后,执行对应的回调
        // if(this.callback.onRejected) {
            // this.callback.onRejected(data);
        // }
        if(this.callbacks.length != 0) {
            this.callbacks.forEach(item => {
                item.onRejected(data);
            })
        }
    }
    ......
}

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

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

相关文章

ceph--理论

分布式存储--------Ceph 前言&#xff1a;随着OpenStack的快速发展&#xff0c;给Ceph的发展注入了强心剂&#xff0c;越来越多的人使用Ceph作为OpenStack的底层共享存储&#xff0c;Ceph在中国的社区也蓬勃发展起来。近两年OpenStack火爆度不及当年&#xff0c;借助于云原生尤…

SoringBoot+VUE前后端分离项目学习笔记 - 【01 环境配置以及VUE2集成ElementUI】

技术栈一览 SpringBoot2 Vue2 ElementUI Axios Hutool Mysql Echarts 所需软件环境 版本一览 JDK 1.8Mysql5.7Node 14.16.0navicatIdea 2021 Vue-cli 安装 npm install -g vue/cli 查看版本 创建VUE工程 初始化工程 vue create vue 选择Manually select feature…

【MySQL】数据库索引 - 浅谈索引类型

索引类型可以分为哈希表、有序数组和 N 叉树 不管是哈希还是有序数组&#xff0c;或者 N 叉树&#xff0c;它们都是基于其自身数据结构的特性来提高读写速度。在 NoSQL 里面还运用到了 LSM 树&#xff0c;来提高写的速度&#xff0c;还有跳表等数据结构来进行优化。 不过需要…

数据结构与算法-java

什么是数组&#xff1f; &#xff08;1&#xff09;数组是计算机中最基本的数据结构之一&#xff0c;我们会用一些名为索引的数字来标识每项数据在数组中的位置。 &#xff08;2&#xff09;大多数编程语言中索引是从0开始的。 &#xff08;3&#xff09;数组在内存中是存在连续…

如何打造一个流式数据湖

Flink将数据写入到 hudi 准备阶段 启动hadoop集群&#xff08;单机模式&#xff09; ./sbin/start-all.shhdfs离开安全模式 hdfs dfsadmin -safemode leave启动hive 后台启动元数据 ./hive --service metastore &启动hiveserver2 ./hiveserver2 &执行sql语句之前…

fpga实操训练(ip rom)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 altera的fpga本身自带了rom的ip&#xff0c;使用起来也十分方便。实际开发中&#xff0c;使用rom的场景也很多&#xff0c;比如一些默认的配置文件…

TensorFlow之回归模型-2

1 基本概念 回归模型 线性 线性模型 非线性模型 线性回归 逻辑回归 Log Loss&#xff08;损失函数&#xff09; 分类临界值 2 效率预测 回归问题是预测一个持续的值&#xff0c;主要是用于解决不确定性的问题&#xff0c;例如&#xff0c;一个商品在未来可能的价格或…

CMAKE_INSTALL_PREFIX

一、定义 CMAKE_INSTALL_PREFIX为cmake的内置变量&#xff0c;用于指定cmake执行install命令时&#xff0c;安装的路径前缀。Linux下的默认路径是/usr/local &#xff0c;Windows下默认路径是 C:/Program Files/${PROJECT_NAME} 二、用…

dcloud如何苹果ios系统真机测试-HBuilderX真机运行ios测试

dcloud如何运行到IOS真机测试 1&#xff0c;下载安装iTunes 安装完毕后重新打开HBuilderX 2&#xff0c;点击运行真机 将iPhone 与电脑进行链接&#xff0c;点信任&#xff0c; 运行-运行到手机或模拟器-运行到IOS APP 基座 安装过itunes就会有显示&#xff0c;但是这里还有…

进程的学习 —— Linux下的进程

目录前言1 认识进程1.1 进程的概念1.2 进程的管理1.3 查看进程的两种方法1.4 getpid、getppid和fork函数2 进程状态2.1 普遍概念下的进程状态2.2 Linux下的进程状态2.2.1 测试Linux的各种进程状态2.2.2 僵尸进程2.3 孤儿进程3 进程切换与进程优先级3.1 并行、并发3.2 进程切换3…

kafka和sparkStreaming

1、Kafka 1、kafka集群架构 producer 消息生产者&#xff0c;发布消息到Kafka集群的终端或服务 broker Kafka集群中包含的服务器&#xff0c;一个borker就表示kafka集群中的一个节点 topic 每条发布到Kafka集群的消息属于的类别&#xff0c;即Kafka是面向 topic 的。 更通俗…

HDFS 常用命令

一、HDFS常用命令 1、查看版本 hdfs version 2、创建 HDFS 文件系统目录。 格式&#xff1a; hdfs dfs -mkdir /user/dir1 3、列出目录下的所有文件 类似 Linux Shell 的 ls 命令。用它可以列出指定目录下的所有文件 hdfs dfs -ls /user/ 4、把本地文件系统文件和目录拷贝…

整合Tkinter GUI界面的古诗词词云生成

Python语言提供的wordcloud词云功能&#xff0c;使文本数据的可视化&#xff0c;简单而美丽。但网上的大多数词云生成功能&#xff0c;多半没有可交互的GUI界面&#xff0c;使用起来稍觉不便。笔者结合网上的中文词云功能&#xff0c;以唐诗三百首&#xff0c;宋词三百首&#…

拟合算法(模型+代码)

拟合的结果是得到一个确定的曲线 最小二乘法的几何解释&#xff1a; argmin 存在参数k&#xff0c;b使括号里的值最小 第一种有绝对值&#xff0c;不易求导&#xff08;求导在求最小值&#xff09;&#xff0c;计算较为复杂&#xff1b;所以我们往往使用第二种定义&#xff0…

什么软件可以录屏?这3款宝藏录屏软件,码住收藏

当我们处理剪辑视频时&#xff0c;我们需要使用到很多素材。有些素材我们可以直接从电脑网上进行下载。但有些素材我们在网上无法进行下载&#xff0c;这个时候就需要使用录屏软件进行录屏。什么软件可以录屏&#xff1f;今天小编向您分享3个宝藏录屏软件&#xff0c;赶紧码住收…

jmeter基础使用方法

文章目录一 配置环境变量二 Jmeter默认语言设置三 启动线程组的创建发送http请求数据报告一 配置环境变量 设置JMETER_HOME,及jemeter解压目录。 设置CLASSPATH,此处分别配置ApacheJMeter_core.jar和jorphan.jar所在位置。 关于环境变量配置多个值&#xff0c;在多个参数中间…

动态规划——状态压缩dp

文章目录概述状态压缩使用条件状压dp位运算棋盘&#xff08;基于连通性&#xff09;类问题概述例题蒙德里安的梦想小国王玉米田炮兵阵地集合类问题概述例题最短Hamilton路径愤怒的小鸟总结概述 状态压缩 状态压缩就是使用某种方法&#xff0c;简明扼要地以最小代价来表示某种…

MySQL 进阶篇2.0 存储过程 触发器 锁 InnoDB引擎

45.存储过程-介绍 46.存储过程-基本语法 -- 查看 select * from information_sc

Python中import语句用法详解

一. 什么是模块&#xff08;module&#xff09;&#xff1f; 在实际应用中&#xff0c;有时程序所要实现功能比较复杂&#xff0c;代码量也很大。若把所有的代码都存储在一个文件中&#xff0c;则不利于代码的复用和维护。一种更好的方式是将实现不同功能的代码分拆到多个文件…

案例丨多元业态管理服务厂商如何走通数字化转型之路

对于多元业态管理服务厂商来说&#xff0c;不同业态客户的使用习惯不一样&#xff0c;从而导致服务过程中的服务有所区别&#xff0c;是这类服务厂商数字化转型的核心需求。下面就以全国领先的阳光智博为例&#xff0c;看下他们是怎样数字化转型的。 一、企业介绍 阳光智博服务…