[Promesa] y [axios] de desarrollo de aprendizaje front-end

0. suplemento

1. Objeto de instancia y objeto de función

Objeto de instancia : el objeto generado por la nueva función;
objeto de función : usar la función como un objeto; (métodos o atributos operativos)

2. Función de devolución de llamada

Definido por usted mismo, pero no llamado por usted mismo, aún se ejecutará.
Devolución de llamada síncrona :
se ejecuta inmediatamente y no finalizará hasta que se ejecute por completo. no se colocará en la cola.
Devolución de llamada asincrónica :
colóquelo en la cola para una ejecución futura. No lo haga directamente al principio, ejecútelo directamente después del inicio y luego ejecute la función de devolución de llamada.

3. Manejo de errores

Tipo de error :

  • ReferenceError: la variable de referencia no existe;
  • TypeError: El tipo de datos es incorrecto; (el tipo no existe propiedad o método xxx)
  • RangeError: fuera de rango, bucle infinito;
  • SyntaxError: error de sintaxis.

Manejo de errores :

  • Error de captura: intente capturar el error de captura. mensaje, pila
  • Lanzar un error: lanzar un nuevo error (' ')

Objeto de error :
atributo del mensaje: información relacionada con el error;
atributo de la pila: información del registro de la pila de llamadas de función.

1. Información general

1. Introducción

Programación asíncrona :

  • operación de archivo
  • operación de base de datos
  • Temporizador

Implementación de programación asíncrona : funciones de devolución de llamada

¿Qué son las Promesas?
Promise es una solución para la programación asíncrona en JS, sintácticamente hablando es un constructor, funcionalmente hablando un objeto de promesa se utiliza para encapsular una operación asíncrona y obtener el valor del resultado de su éxito o fracaso.

Promise es una clase proporcionada por ECMAScript 6 para escribir tareas asincrónicas complejas de manera más elegante.

Por qué usar Promesa :

  1. Especifique la función de devolución de llamada, que es más flexible: inicie la tarea asíncrona, devuelva el objeto de promesa, vincule la función de devolución de llamada al objeto de promesa; en el pasado, la función de devolución de llamada debe prepararse antes de iniciar la tarea asíncrona;
  2. Admite llamadas en cadena para resolver el problema del infierno de devolución de llamada (avance continuo, siempre anidado).

2. Estado de promesa

  1. pendiente pasa a ser resuelta
  2. pendiente 变 rechazado
  • Promise solo tiene estos dos estados, y un objeto solo se puede cambiar una vez;
  • Independientemente del éxito o el fracaso, solo hay un dato de resultado;
  • El resultado del éxito es el valor, y el resultado del fracaso es la razón.

Proceso :
inserte la descripción de la imagen aquí

3. Usa el proceso Promesa

Promise es un constructor que puede instanciar un objeto. El parámetro que recibe es un valor del tipo de función. Esta función tiene dos parámetros formales, resolver y rechazar (también datos del tipo de función). falla

const p=new Promise((resolve,reject)=>{
    
    
//执行器函数 执行异步操作任务
//成功则调用resolve(value),将promise对象的状态设置为成功
//失败调用reject(reason),将promise对象的状态设置为失败
})

luego método:
recibe dos parámetros, ambos valores de tipo función. Si tiene éxito, se ejecuta la primera función de devolución de llamada y, si falla, se ejecuta la segunda función de devolución de llamada.

p.then(()=>{
    
    },()=>{
    
    })

4. Use el paquete util.pormisify (original)

Pase una función de devolución de llamada de error primero (es decir, tome (err,value)=>{}una devolución de llamada como último argumento) y devuelva una versión prometida.
El módulo util incorporado de Node.js tiene un método promisify() que convierte una función basada en devolución de llamada en una función basada en Promise. Esto le permite usar cadenas Promise y async/await con API basadas en devolución de llamadas.

//引入util模块
const util=require('util');
//引入fs模块
const fs=require('fs');
//返回一个新函数
let mineReadFile=util.promisify(fs.readFile);
mineReadFile('./resource/content.txt').then(value=>{
    
    });

5. Encapsular solicitud AJAX

function sendAJAX(url){
    
    
	return new Promise((resolve,reject)=>{
    
    
	const xhr=new XMLHttpRequest();
	xhr.open("GET",url);
	xhr.send();
	xhr.onreadystatechange=function(){
    
    
		if(xhr.readystate===4){
    
    
			if(xhr.status>=200&&xhr.status<300)
			{
    
    
				resolve(xhr.response);
			}else{
    
    
				reject(xhr.status);
			}
		}
	}
}

sendAJAX('http://api')
.then(value=>{
    
    },reason=>{
    
    })

2. Teoría

1. Estado de promesa

Una propiedad PromiseState en el objeto de instancia

  • pendiente indeciso
  • resuelto, completado con éxito
  • rechazado fallido

Un objeto de promesa solo se puede cambiar una vez, y solo hay un resultado de datos, los datos de éxito son el valor y los datos de falla son la razón.

2. El valor del objeto Promise

Otro atributo PromiseResult en el objeto de instancia
contiene el resultado del éxito o fracaso del objeto.
Función para modificar el valor:

  • resolver;
  • rechazar.

Luego llame al método entonces para realizar operaciones relacionadas en el valor.

3. API

Preste atención para ver si pertenece a un objeto de función oa un objeto de instancia.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
resolver :
si el parámetro entrante es un objeto que no es de promesa, el resultado devuelto es un objeto de promesa exitoso; si el parámetro entrante es un objeto de promesa, el resultado del parámetro es el resultado de resolver.
Si falla, debe atraparlo con catch.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

4. Preguntas clave

Cómo cambiar el estado de la promesa :

  • Llame a la función de resolución o a la función de rechazo;
  • throw ' 'arroja un error.

Una promesa especifica múltiples devoluciones de llamada, ¿se llamarán todas ?:

  • Se llama cuando la promesa cambia al estado correspondiente.

El orden de cambiar el estado de la promesa y especificar la función de devolución de llamada :

  • Es posible, en circunstancias normales, primero especificar la devolución de llamada (luego) y luego cambiar el estado;
  • Cómo cambiar el estado primero y luego especificar la devolución de llamada: llamar directamente a resolver o rechazar en el ejecutor, retrasar la llamada entonces;
  • Cuándo obtener los datos: si se especifica primero la devolución de llamada, cuando cambie el estado, se llamará a la función de devolución de llamada para obtener los datos; si primero se cambia el estado, se llamará a la devolución de llamada para obtener los datos cuando se especifique la devolución de llamada .

luego devuelve el estado resultante del objeto de promesa :

  • Determinado por el resultado de la ejecución de la función de devolución de llamada especificada por then();
    inserte la descripción de la imagen aquí
    inserte la descripción de la imagen aquí

Penetración de excepción :
si se lanza una excepción antes, se puede atrapar al final y luego se puede llamar en el medio.
inserte la descripción de la imagen aquí

3. Promesa personalizada

usar:

let p=new Promise((resolve,reject)=>{
    
    
	resolve('ok');
});
p.then(value=>{
    
    },reason=>{
    
    });

personalizar:

  1. Defina la estructura general: el constructor contiene el parámetro ejecutor (tipo de función) y la función luego se agrega a la cadena de prototipos; las funciones de rechazo y resolución se declaran en el constructor, se llama al ejecutor y los parámetros son rechazo y resolver;
  2. Configure las funciones de rechazo y resolución: primero agregue las propiedades PromiseState y PromiseResult y configure el valor inicial; luego guarde el objeto de instancia this y luego modifique las variables en las dos funciones (tenga en cuenta que la función tiene los datos del parámetro formal como valor de resultado );
  3. throw lanza una excepción: use try catch para atrapar la excepción al llamar al ejecutor, y llame al rechazo;
  4. La configuración del estado Promise solo se puede modificar una vez: configure el juicio en las funciones de rechazo y resolución, si el estado no está pendiente, regrese directamente sin modificación;
  5. El método entonces ejecuta la devolución de llamada: el método entonces tiene dos parámetros formales de tipo función onResolved y onRejected, y el primero se llama cuando se cumple el estado (el parámetro formal es el valor del resultado);
  6. Ejecución de devolución de llamada de tarea asíncrona: para poder especificar una devolución de llamada cuando el estado no ha cambiado, es necesario hacer un juicio pendiente en ese momento, agregar una variable de devolución de llamada y guardar las dos funciones de devolución de llamada onRejected y onResolved; agregar un devolución de llamada a la resolución y rechazo del constructor;
  7. Especifique la implementación de múltiples devoluciones de llamada: la devolución de llamada se cambia a una matriz y se pueden enviar varios objetos, cada objeto contiene un onResolved y un onRejected; modifique y llame a cada devolución de llamada en las funciones de resolución y rechazo;
  8. Estado de modificación de tareas sincrónicas devolución del resultado del método then: el resultado devuelto de then está determinado por el resultado de ejecución de la función de devolución de llamada. Modifique la función then y devuelva el objeto Promise recién creado. Si el resultado es una promesa, devuelva el resultado de then llamada Si no es un objeto de promesa, entonces Llamar a resolver para regresar;
  9. Estado de modificación de tareas asincrónicas y luego devolución de resultados del método: agregue juicio pendiente a lo anterior;
  10. Luego optimización del método: encapsulación hen的返回结果由回调函数的执行结果来决定,修改then函数,返回新建的Promise对象,如果结果是promise,则返回其then调用结果,如果不是promise对象,则调用resolve返回;
  11. Método de captura (penetración de excepción y transferencia de valor):
  12. Encapsule las funciones de resolución, rechazo, todo, carrera;
  13. La función de devolución de llamada del método then se ejecuta de forma asíncrona: agregue un temporizador;
  14. Encapsulado en una clase:
function Promise(executor){
    
    
	//添加属性
	this.PromiseState='pending';
	this.PromiseResult=null;
	this.callbacks={
    
    };
	//保存实例对象的this值
	const self=this;
	function resolve(data){
    
    
		if(self.PromiseState !=='pending')return;
		//1.修改对象状态(promiseState)
		self.PromiseState='fulfilled';
		//2.设置对象结果值(promiseResult)
		self.PromiseResult=data;
		setTimeout(()=>{
    
    
			self.callbacks.forEach(item=>{
    
    
				item.onResolved(data);
			})
		})
	}
	function reject(data){
    
    
		if(self.PromiseState !=='pending')return;
		//1.修改对象状态(promiseState)
		self.PromiseState='rejected';
		//2.设置对象结果值(promiseResult)
		self.PromiseResult=data;
		setTimeout(()=>{
    
    
			self.callbacks.forEach(item=>{
    
    
				item.onRejected(data);
			})
		})
		
	}
	try{
    
    
		//同步调用执行器函数
		excutor(resolve,reject);
	}catch(e){
    
    
		reject(e);
	}
	
}
//形参为函数
Promise.prototype.then=function(onResolved,onRejected){
    
    
	const self=this;
	if(typeof onRejected !=='function'){
    
    
		onRejected=reason=>{
    
    
			throw reason;
		}
	}
	if(typeof onResolved!=='function'){
    
    
		onResolved=value=>value;
	}
	return new Promise((resolve,reject)=>{
    
    
		//封装函数
		function callback(type){
    
    
			try{
    
    
				let result=type(this.PromiseResult);
				if(result istanceof Promise){
    
    
					result.then(v=>{
    
    
						resolve(v);
					},r=>{
    
    
						reject(r);
					})
				}else{
    
    
					resolve(result);
				}
			}catch(e){
    
    
				reject(e);
			}
		}
		//调用回调函数
		if(this.PromiseState==='fulfilled'){
    
    
			setTimeout(()=>{
    
    
				callback(onResolved);
			})
		}
		if(this.PromiseState==='rejected'){
    
    
			setTimeout(()=>{
    
    
				callback(onRejected);
			})
			
		}
		if(this.PromiseState==='pending'){
    
    
			//保存回调函数
			this.callbacks.push{
    
    
				onResolved:function(){
    
    
					callback(onResolved);
				},
				onRejected:function(){
    
    
					callback(onRejected);
				}
			}
		}
	})
}
Promise.prototype.catch=function(onRejected){
    
    
	return this.then(ondefined,onRejected);
}

Promise.resolve=function(value){
    
    
	return new Promise((resolve,reject)=>{
    
    
		if(value instanceof Promise){
    
    
			value.then(v=>{
    
    
				resolve(v)
			},r=>{
    
    
				reject(r);
			}
		}else{
    
    
			resolve(value);
		}
	}
}
Promise.reject=function(reason){
    
    
	return new Promise((resolve,reject)=>{
    
    
		reject(reason);
	}
}
Promise.all=function(promises){
    
    
	return new Promise((resolve,reject)=>{
    
    
		let count=0;
		let arr=[];
		for(let i=0;i<promises.length;i++){
    
    
			promises[i].then(v=>{
    
    
				count++;
				arr[i]=v;
				if(count===promises.length){
    
    
					resolve(arr);
				}
			},r=>{
    
    
				reject(r);
			})
		}
	}
}
Promise.race=function(promises){
    
    
	return new Promise((resolve,reject)=>{
    
    
		for(let i=0;i<promises.length;i++){
    
    
			promises[i].then(v=>{
    
    
				resolve(v);
			},r=>{
    
    
				reject(r);
			})
		}
	}
}
class Promise{
    
    
	constructor(executor){
    
    
			//添加属性
	this.PromiseState='pending';
	this.PromiseResult=null;
	this.callbacks={
    
    };
	//保存实例对象的this值
	const self=this;
	function resolve(data){
    
    
		if(self.PromiseState !=='pending')return;
		//1.修改对象状态(promiseState)
		self.PromiseState='fulfilled';
		//2.设置对象结果值(promiseResult)
		self.PromiseResult=data;
		setTimeout(()=>{
    
    
			self.callbacks.forEach(item=>{
    
    
				item.onResolved(data);
			})
		})
	}
	function reject(data){
    
    
		if(self.PromiseState !=='pending')return;
		//1.修改对象状态(promiseState)
		self.PromiseState='rejected';
		//2.设置对象结果值(promiseResult)
		self.PromiseResult=data;
		setTimeout(()=>{
    
    
			self.callbacks.forEach(item=>{
    
    
				item.onRejected(data);
			})
		})
		
	}
	try{
    
    
		//同步调用执行器函数
		excutor(resolve,reject);
	}catch(e){
    
    
		reject(e);
	}
	}
	then((onResolved,onRejected){
    
    
	const self=this;
	if(typeof onRejected !=='function'){
    
    
		onRejected=reason=>{
    
    
			throw reason;
		}
	}
	if(typeof onResolved!=='function'){
    
    
		onResolved=value=>value;
	}
	return new Promise((resolve,reject)=>{
    
    
		//封装函数
		function callback(type){
    
    
			try{
    
    
				let result=type(this.PromiseResult);
				if(result istanceof Promise){
    
    
					result.then(v=>{
    
    
						resolve(v);
					},r=>{
    
    
						reject(r);
					})
				}else{
    
    
					resolve(result);
				}
			}catch(e){
    
    
				reject(e);
			}
		}
		//调用回调函数
		if(this.PromiseState==='fulfilled'){
    
    
			setTimeout(()=>{
    
    
				callback(onResolved);
			})
		}
		if(this.PromiseState==='rejected'){
    
    
			setTimeout(()=>{
    
    
				callback(onRejected);
			})
			
		}
		if(this.PromiseState==='pending'){
    
    
			//保存回调函数
			this.callbacks.push{
    
    
				onResolved:function(){
    
    
					callback(onResolved);
				},
				onRejected:function(){
    
    
					callback(onRejected);
				}
			}
		}
	})
}

	catch(onRejected){
    
    
		return this.then(ondefined,onRejected);
	}

	static resolve(value){
    
    }
	static reject(reason){
    
    }
	static all(promises){
    
    }
	static race(promises){
    
    }
}

4. asíncrono y espera

1. función asíncrona

  • El valor de retorno es un objeto de promesa;
  • El resultado del objeto de promesa está determinado por el valor de retorno de la ejecución de la función asíncrona: si el valor de retorno es un objeto que no es de promesa, el resultado es un objeto de promesa en un estado exitoso y el valor de resultado es el valor de retorno; si el resultado devuelto es un objeto de promesa, se devuelve el objeto; si se lanza una excepción, devuelve una promesa fallida y el valor del resultado es el valor lanzado.

2. espera expresión

  • La expresión en el lado derecho de await es generalmente un objeto de promesa y también puede ser otros valores;

  • Si la expresión es un objeto de promesa, await devuelve el valor del resultado de la promesa exitosa;

  • Si el lado derecho es un objeto de promesa fallida, debe ser capturado por try catch para obtener el resultado fallido;

  • Si la expresión es otro valor, use directamente este valor como el valor de retorno de await.

  • await debe escribirse en la función asíncrona, pero no puede haber espera en la función asíncrona;

  • Si la promesa de await falla, se lanzará una excepción, que debe ser capturada y procesada por try catch.

3. Combinación de asíncrono y espera

  1. El manejo de errores y la devolución de llamada son más convenientes: captura de prueba directa;
  2. Al enviar ajax, llame directamente a la función encapsulada.

5.axios

1. Introducción

Axios es una encapsulación basada en promesas de ajax. Axios es una biblioteca de solicitud de red basada en promesas para node.js y el navegador. Es isomorfo (es decir, el mismo código puede ejecutarse en el navegador y node.js). En el lado del servidor usa el módulo http nativo de node.js, y en el lado del cliente (lado del navegador) usa XMLHttpRequests.

mvvm:
inserte la descripción de la imagen aquí

2. Uso básico

De forma predeterminada, el método get se usa para enviar una solicitud sin parámetros :

axios({
    
    
	url:'https://api'
}).then(res=>{
    
    })

Especifique el método get para enviar una solicitud sin parámetros :

axios({
    
    
	url:'https://api'method:'get'
}).then(res=>{
    
    })

Especifique el método de publicación para enviar una solicitud sin parámetros :

axios({
    
    
	url:'https://api'method:'post'
}).then(res=>{
    
    })

get envía una solicitud con parámetros :

axios({
    
    
	url:'https://api?key=value',
	method:'get'
}).then(res=>{
    
    })
axios({
    
    
	url:'https://api',
	params:{
    
    
		key:'value',
	},
	method:'get'
}).then(res=>{
    
    })

post envía una solicitud con parámetros :

axios({
    
    
	url:'https://api',
	params:{
    
    
		key:'value',
	},
	method:'post'
}).then(res=>{
    
    })

Si se usan datos en lugar de parámetros para enviar, el valor recibido en segundo plano es nulo, porque axios usa la publicación para transportar parámetros de manera predeterminada usando application/json.
Solución: 1. Use params 2. Agregue @requestBody a los parámetros de solicitud en el lado del servidor.

3. Método de solicitud de Axios

get no tiene parámetros :

axios.get('url').then(res=>{
    
    }).catch(err=>{
    
    })

get tiene parámetros :

axios.get('url',{
    
    parmas:{
    
    key:'value'}}).then(res=>{
    
    }).catch(err=>{
    
    })

publicar sin parametros :

axios.post('url').then(res=>{
    
    }).catch(err=>{
    
    })

La publicación tiene parámetros :

axios.post('url',"key=value&key2=value2").then(res=>{
    
    }).catch(err=>{
    
    })

Para usar datos para transferir datos, el fondo debe convertir automáticamente axuios en objetos java, además de @requestBody.
inserte la descripción de la imagen aquí

4. Solicitudes simultáneas de Axios

Una serie de respuestas exitosas a las solicitudes.
Puede utilizar el método de función de distribución para procesar el resultado de la respuesta.

axios.all([
	axios.get('url'),
	axios.post('url')])
.then(
	axios.spread((res1,res2)=>{
    
    })
).catch(err=>{
    
    })

5. Configuración global

Especifica la configuración predeterminada, que se aplicará a cada solicitud.

axios.defaults.baseURL='';
axios.defaults.timeout=2000;

6. Ejemplos

Encapsule diferentes instancias para lograr diferentes configuraciones

let newVar=axios.create({
    
    
	baseURL:'',
	timeout:5000
});
newVar({
    
    
	url:''
}).then(res=>{
    
    })

7. interceptor

Las acciones se procesan antes de iniciar una solicitud o respuesta, interceptándolas antes de que se procesen o capturen. aproximadamente igual al filtro

Axios dos tipos de interceptores: interceptación en la dirección de solicitud e interceptación en la dirección de respuesta.

// 添加请求拦截器
axios.interceptors.request.use(config=>{
    
    
    // 在发送请求之前做些什么
    return config;
  }, error=>{
    
    
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(response=>{
    
    
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, error=>{
    
    
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });

Retire el interceptor:

const myInterceptor = axios.interceptors.request.use(function () {
    
    /*...*/});
axios.interceptors.request.eject(myInterceptor);

8. Módulo de encapsulación de axios en vue

  1. Instalarnpm install --save
  2. Cree una carpeta de solicitud para almacenar la función de solicitud;
  3. encapsulación

Pasar parámetros:

import axios from 'axios';
export function request(config,success,fail){
    
    
	axios({
    
    
		url:config
	}).then(res=>{
    
    success();})
	.catch(err=>{
    
    fail();})
}

export function request1(config){
    
    
	axios.defaults,baseURL='';
	axios(config).then(res=>{
    
    config.success(res);})
	.catch(err=>{
    
    config.fail(err);})
	// config={url:'',success:res=>{},fail:err=>{}}
}

promesa:

export function request(config){
    
    
	return new Promise((resolve,reject)=>{
    
    
		let newVar=axios.create({
    
    
			baseURL:'',
			timeout:5000
		});
		newVar(config).then(res=>	{
    
    resolve(res);}).catch(err=>{
    
    reject(err);})
	})
}
//调用
request({
    
    url:''}).then(res=>{
    
    }).catch(err=>{
    
    })

Crea una instancia:

export function request(config){
    
    
	let newVar=axios.create({
    
    
		baseURL:'',
		timeout:5000
	});
	return newVar(config);
}

request({
    
    
	url:''}).then(res=>{
    
    })

Capacidad para realizar análisis de código fuente

Supongo que te gusta

Origin blog.csdn.net/qq_46056318/article/details/127338993
Recomendado
Clasificación