Je me bats toujours avec les promesses, mais je fais des progrès grâce à la communauté d’ici.
J'ai une simple fonction JS qui interroge une base de données Parse. Elle est supposée renvoyer le tableau de résultats, mais à cause de la nature asynchrone de la requête (d'où les promesses), la fonction retourne avant les résultats, me laissant avec un tableau non défini.
Que dois-je faire pour que cette fonction attende le résultat de la promesse?
Voici mon code:
function resultsByName(name)
{
var Card = Parse.Object.extend("Card");
var query = new Parse.Query(Card);
query.equalTo("name", name.toString());
var resultsArray = [];
var promise = query.find({
success: function(results) {
// results is an array of Parse.Object.
console.log(results);
//resultsArray = results;
return results;
},
error: function(error) {
// error is an instance of Parse.Error.
console.log("Error");
}
});
}
Au lieu de renvoyer resultsArray
, vous renvoyez une promesse pour un tableau de résultats, puis then
sur le site d’appel. Cela présente l’avantage supplémentaire de l’appelant de savoir que la fonction effectue des E/S asynchrones. La concurrence de codage en JavaScript est basée sur cela - vous voudrez peut-être lire cette question pour avoir une idée plus large:
function resultsByName(name)
{
var Card = Parse.Object.extend("Card");
var query = new Parse.Query(Card);
query.equalTo("name", name.toString());
var resultsArray = [];
return query.find({});
}
// later
resultsByName("Some Name").then(function(results){
// access results here by chaining to the returned promise
});
Vous pouvez voir plus d'exemples d'utilisation de promesses d'analyse avec des requêtes dans le blog de Parse à ce sujet .
Que dois-je faire pour que cette fonction attende le résultat de la promesse?
Utilisez async/await
(NON inclus dans ECMA6, mais disponible pour Chrome, Edge, Firefox et Safari depuis fin 2017, voir canIuse )
MDN
async function waitForPromise() {
// let result = await any Promise, like:
let result = await Promise.resolve('this is a sample promise');
}
Ajout dû au commentaire: Une fonction asynchrone retourne toujours une promesse, et dans TypeScript cela ressemblerait à:
async function waitForPromise(): Promise<string> {
// let result = await any Promise, like:
let result = await Promise.resolve('this is a sample promise');
}
Vous ne voulez pas faire attendre la fonction, car JavaScript est censé ne pas être bloquant. Au lieu de retourner la promesse à la fin de la fonction, la fonction appelante peut alors utiliser la promesse pour obtenir la réponse du serveur.
var promise = query.find();
return promise;
//Or return query.find();
Vous n'utilisez pas réellement les promesses ici. Parse vous permet d'utiliser des rappels ou des promesses; votre choix.
Pour utiliser les promesses, procédez comme suit:
query.find().then(function() {
console.log("success!");
}, function() {
console.log("error");
});
Maintenant, pour exécuter des commandes une fois la promesse terminée, vous pouvez simplement l'exécuter dans le rappel de promesse dans l'appel then()
. Jusqu'ici, ce serait exactement la même chose que les rappels réguliers.
Pour bien utiliser les promesses, c’est lorsque vous les enchaînez, comme ceci:
query.find().then(function() {
console.log("success!");
return new Parse.Query(Obj).get("sOmE_oBjEcT");
}, function() {
console.log("error");
}).then(function() {
console.log("success on second callback!");
}, function() {
console.log("error on second callback");
});
J'ai le même problème, donc je maintiens du code, le code nécessite un appel ajax pour traiter une autre tâche, voici mon code
this.bindChangeEvent = function () {
//select all bind change
this._select_all.bind('change', function () {
console.log('All')
if ($(this).is(":checked")) {
///todo: call ajax to get all ids
var idsAllItem = pointer.getAllData();
console.log(idsAllItem);
console.log('Another todo');
Fonction Ajax
this.getAllData = function() {
var promises = [];
var def = new $.Deferred();
return new Promise((resolve, reject) => {
// AJAX request
var url = '...';
$.ajax({
url: url,
type: "get",
async: true,
data: {},
dataType: "json",
success: function (data) {
console.log('Ajjax done');
resolve(data)
},
error: function (err) {
reject(err)
}
});
})
};
et j'obtiens le résultat
Another todo
Output
Ajax Done
….