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 Date
o 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 ? "
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 Date
em 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: