Problemas usando Deferred/When em jquery para adiar uma função
-
21-12-2019 - |
Pergunta
Estou realmente lutando para usar Deferred ou When com meu script jquery.Já li vários artigos aqui e em outros lugares (incluindo api.jquery.com) e acho que sou um pouco iniciante para entender exatamente como usar essas chamadas.
Estou tentando adiar a execução de uma função até que uma função anterior em meu script seja concluída.
Eu tenho
function datapoints () {
//My long function here where I define $data
};
cujo resultado é uma matriz chamada $data.Preciso que a variável $data seja definida na minha próxima função, então quero adiá-la.
Tentei configurar o adiamento assim:
var deferred = $.Deferred();
deferred.resolve(datapoints());
deferred.done(function result (){
// My function here where I use $data
}
);
Eu realmente aprecio algumas dicas sobre como limpar isso.Tentei recriar vários exemplos, mas sempre o resultado é um erro de console dizendo que $data é indefinido.Eu sei que o código funciona porque quando coloco manualmente um setTimeout de alguns segundos antes de executar a segunda função, tudo funciona bem, mas acho que adiado é uma solução melhor.
Desde já, obrigado!
Solução
Tente corrigir seu código assim:
deferred.done(function result (data){
// Do not use global $data, use local 'data' instead
}
);
Isso garantirá que os dados que você está usando sejam de fato os dados retornados por datapoints()
.
Você também deve estar ciente de que, a menos que datapoints()
é uma função assíncrona, o código que você escreveu IRÁ bloquear o thread JS (ou seja,se executado no navegador - bloqueará a IU).
Promessas/adiadas com funções síncronas não são de muita utilidade.
O padrão usual seria algo assim:
function datapoints() {
var d = $.Deferred()
asyncCallToCreateDatapoints(function callback(data) {
d.resolve(data)
})
return d;
}
datapoints().done(function result(data) {
/* do stuff with data */
})
Outras dicas
Experimente este código:
function datapoints () {
var deferred = $.Deferred();
/* later, when data is ready, call:
deffered.resolve(data);
*/
return deferred.promise();
}
datapoints().then(function () {
// runs when data is ready
})
Não tenho certeza de qual é o seu problema, mas isso jsfiddle está funcionando bem para mim.
function datapoints () {
//My long function here where I define $data
return {"datapoint1": 1, "datapoint2": 2};
};
var deferred = $.Deferred();
deferred.resolve(datapoints());
deferred.done(function result (data){
// My function here where I use $data
console.log("data: ", data);
});