2017-10-02 11 views
2

Comment intégrer Discovery avec Conversation? J'utilise NodeJS, mais j'ai des problèmes parce que je veux que les résultats de la conversation viennent après en interrogeant ma collection de données. J'essaie d'utiliser les rappels, mais pas de chance pour le moment. Je pourrais utiliser async, mais pourrais-je utiliser de simples rappels dans ce cas? Aide appréciée, merci!Fonctions de rappel et fonctions asynchrones

function updateMessage(res, data) { 
    if (!data.output) { 
    data.output = {}; 
    } else { 
    /* THIS CODE RETURNS CONVERSATION DATA FIRST, CAUSING THE DISCOVERY QUERY 
    TO BECOME UNDEFINED */ 
    if (data.context.callDiscovery === true) { 
     //Query collection 
     Discovery.query(params, function(error, results) { 
     data.output.text = "Getting what you need"; 

     //Set output graph card 
     data.output.graph = { 
      title: results.title, 
      url: result.url, 
      description: results.passage_text 
     }; 

     return results; 
     }); 
    } 
    return data; 
    } 
} 
+0

est-ce pas le problème que vous retournez des données en dehors de la fonction de requête, de sorte que le rappel ne soit pas exécuté comme vous avez déjà sorti du champ de fonction? – linasmnew

+0

Je m'excuse @linasmnew. J'ai inclus la fonction complète maintenant. Il doit retourner en dehors de la portée dans le cas où les données retournées n'ont pas de données spécifiées. Sortie – agomez

Répondre

3

Vous mélangez des opérations de synchronisation et d'exécution asynchrone.

Voici un exemple d'une fonction de retour synchrone:

function (options) { 
    if (options.flag) { 
    return "Flag is set"; 
    } else { 
    return "Flag is not set"; 
    } 
} 

Voici un exemple d'une fonction de retour de manière asynchrone:

function (options, done) { 
    Discovery.query({options}, function (err, results) { 
    if (err) return done(err); 
    return done(null, results); 
    }); 
} 

Cependant, il est recommandé de ne pas retourner une fonction d'accepter le rappel immédiatement en fonction d'une condition ou effectuer une opération asynchrone et ensuite revenir. Si votre fonction ne prend pas de rappel et n'appelle pas ce rappel lorsque l'opération async est terminée, votre fonction sera exécutée avant la fin des opérations asynchrones. Par exemple:

function mixedUp(options) { 
    Discovery.query({options}, function (err, results) { 
    if (err) return err; 
    return results; 
    }); 
    return 'default value'; 
} 

Cela renverra toujours la valeur par défaut, car avant la demande de découverte est terminée, votre fonction est de retour.

Vous devriez faire en sorte que votre fonction accepte un callback ou un paramètre done, qui dans le nœud idiomatique est le dernier argument de votre fonction. function (options, moreOptions, done/callback/cb) devrait être la signature de votre fonction. Ensuite, votre fonction doit appeler cette fonction de rappel lorsque vous souhaitez effectuer une action.

function updateMessage(res, data, done) { 
    if (!data.output) { 
    data.output = {}; 
    return done(null, data); 
    } else { 
    /* THIS CODE RETURNS CONVERSATION DATA FIRST, CAUSING THE DISCOVERY QUERY 
    TO BECOME UNDEFINED */ 
    if (data.context.callDiscovery === true) { 
     //Query collection 
     Discovery.query(params, function(error, results) { 
     data.output.text = "Getting what you need"; 

     //Set output graph card 
     data.output.graph = { 
      title: results.title, 
      url: result.url, 
      description: results.passage_text 
     }; 

     return done(null, results); 
     }); 
    } else { 
     return done(null, data); 
    } 
    } 
} 
+0

Merci beaucoup pour vos explications détaillées. Vous m'avez aidé à mieux comprendre les rappels. Cependant, quand j'ai ajouté vos suggestions, j'ai 'fait n'est pas défini». Pourquoi est-ce? – agomez

+0

Bien sûr, je suis content que cela vous ait été utile. Lorsque vous appelez la fonction, par ex. updateMessage (res, data) - vous devez lui fournir une fonction de rappel qui définira done. par exemple. 'updateMessage (res, données, fonction (err, res) {console.log (err, res)});' ceci aura été défini lors de l'exécution de l'appelé et l'appelant obtiendra les résultats une fois terminé. –