Use a promessa de implementar um processamento de solicitação de tempo limite

O entrevistador me fez esta pergunta hoje. Para ser sincero, fiquei chocado.
Eu primeiro pensei que acabou sendo: ~ Este problema chora muito simples ah, não que use Dateo objeto para determinar se é maior do que uma certa diferença de tempo? Então, escrevi o seguinte código:

let rest=function(){
    
    
	// 开始是放在外面的,但是面试官说要尽可能不单独暴露值,于是鬼迷心窍(紧张)杀都没想就直接扔进来了...
	let date=Date.now();
	return new Promise((resolve,reject)=>{
    
    
		let _date=Date.now();
		if(_date-date>2000){
    
    
			reject('请求超时');
		}
		resolve();
	})
}

Quando eu estava secretamente orgulhoso de que estava prestes a terminar, como o entrevistador me disse que a entrevista havia passado, o outro lado disse de repente:
"Você, tem certeza que quer fazer isso?"
"Suas condições se realmente serão implementadas ? "
o que!
De repente, senti que algo estava errado e fiquei chocado. Quando eu estava prestes a dar uma olhada mais de perto, o entrevistador já havia dito" Ok, pense sobre essa questão novamente, esta entrevista vai terminar aqui. "

Depois de descer, pense bem. A premissa de "baseado em promessa" já sugeriu que "os recursos de promessa devem ser aplicados tanto quanto possível." Então, o que deve ser usado nesta pergunta?

Lembrei-me deste artigo que escrevi há dois dias: Implementando um Ajax "interrompível" . É mencionado que o método " rejeitar " pode ser usado para suspender a execução de callbacks subsequentes!

Uma coisa a lembrar aqui: uma vez que a alteração do valor do estado da promessa é acionada, ela é irreversível, portanto, é impossível realmente "interromper" a promessa. Só se pode dizer que o retorno de chamada "bem-sucedido" não pode ser executado por meio do sistema síncrono e assíncrono seqüência (evento Loop).

Parece que percebi de repente ...

Mas ainda há um problema: como julgar o "tempo limite"?
Se nada mais, você coloca dois Dateem uma função; em qualquer caso, seus valores são os mesmos! Então eu pensei sobre isso setTimeout! Com este tempo de processamento assíncrono, meu pensamento ficará claro: há uma API nomeada na promessa:, Promise.race()e all()a diferença é, corrida em que há uma promessa de alterar o valor do status quando seus resultados forem executados imediatamente, como este:

let rest=function(_data=1000){
    
    
	return Promise.race([
		upload().then(data=>{
    
    console.log(data.data)}),
		uploadTimeout(_data)
	])
}
function upload(){
    
    
	console.log('请求进行中...');
	return new Promise((resolve,reject)=>{
    
    
		let xhr=new XMLHttpRequest();
		xhr.open('GET',"https://devapi.qweather.com/v7/weather/24h?location=这里是纬度和经度英文逗号分搁&key=这里是百度地图的key");
		xhr.onload=function(){
    
    
			if(xhr.readyState==4 && (xhr.status>=200 && xhr.status<300)){
    
    
				setTimeout(()=>{
    
    
					resolve({
    
    data:JSON.parse(xhr.responseText)})
				},2000)
			}else{
    
    
				reject(xhr.status)
			}
		}
		xhr.onerror=function(){
    
    
			reject('请求失败了...')
		}
		xhr.send(null);
		// 【1】
	})
};
function uploadTimeout(times){
    
    
	return new Promise((resolve,reject)=>{
    
    
		setTimeout(()=>{
    
    
			reject('请求超时,请重试');   // 【2】
		},times)
	})
}

Neste ponto, a função é basicamente realizada, mas após a execução, você verá que a primeira função ainda é executada após o erro ser relatado!
Sim, isso é o que disse acima: o processo de alteração do valor do estado de promessa é irreversível. E embora você retorne rejeitar abaixo, mas essas são duas promessas, não há conflito entre elas!

Inspirados pela preempção de rejeição mencionada acima , podemos escrever esse código no local marcado como [1] no código:

// 向外暴露取消函数
cancelFn=function(msg){
    
    
	reject('请求超时,请重试');
}

Em seguida, substitua o código marcado como [2] no código por:

cancelFn();

Neste ponto, uma função de "processamento de solicitação de tempo limite" é realmente implementada:
visualizar

Acho que você gosta

Origin blog.csdn.net/qq_43624878/article/details/115265504
Recomendado
Clasificación