javascript - Problème rencontré lors de l'implémentation asynchrone de Nodejs
黄舟
黄舟 2017-07-03 11:41:44
0
6
828

Par exemple, il existe trois fonctions a, b et c, qui effectuent toutes des opérations de synchronisation. Pour simplifier, j'ai simplifié les opérations de synchronisation

.
function c(m) {
    m = m + 1;
    return m;
}
function b(m) {
    m = m + 1;
    return c(m);
}
function a(){
    let m = 0;
    return b(m);
}

Le résultat de l'exécution de a() est 2
Mais si la fonction c n'exécute pas une fonction synchrone, mais une opération asynchrone, par exemple

function c(m) {
    setTimeout(function () {
        m = m + 1;
    }, 1000)
    return m;
}

Lors de l'exécution de a(), si vous souhaitez afficher correctement 2, vous devez encapsuler c via promise ou async,
Similaire à

function promiseC(m) {
    return new Promise((resolve, reject) => {
        setTimeout(function () {
        m = m + 1;
        resolve(m);
        }, 1000)
    }
}
async function c(m) {
    m = await promiseC(m);
    return m; 
}

Parce que c devient une fonction asynchrone, b doit appeler c, b doit également être modifié en asynchrone, et ainsi de suite, a doit également être modifié en asynchrone

async function b(m) {
    m = m + 1;
    return await c(m);
}
async function a(){
    let m = 0;
    return await b(m);
}

a().then(function(data) {

console.log(data)

}) De cette façon, 2

peut être sorti

Afin d'afficher correctement 2, j'ai modifié a et b. Je me demande s'il existe un autre moyen d'éviter de modifier a et b et d'obtenir le résultat correct ?
Comme je n'ai pas pris en compte la situation asynchrone lorsque j'ai commencé à écrire le code, des fonctions comme a et b sont distribuées dans différents fichiers, et il y en a beaucoup. Maintenant, afin de permettre à c d'effectuer des opérations asynchrones, c'est le cas. trop difficile de les changer. Je ne sais pas. Avez-vous d'autres bonnes méthodes ?

Ce qui suit est une question nouvellement ajoutée
Le problème ci-dessus peut être résolu en renvoyant directement l'objet de promesse dans la réponse ci-dessous, mais la structure réelle du code ressemble davantage à ceci

function c(m) {
    m = m + 1;
    return m;
}
function b(m) {
    m = m + 1;
    let n = c(m)
    n = n + 1
    return n;
}
function a(){
    let m = 0;
    let k = b(m);
    k = k + 1;
    return k;
}

Si je suis cette méthode, je dois modifier les méthodes de retour de a et b
afin que a et b puissent renvoyer des objets promis
Pour une telle structure, je ne sais pas s'il existe un moyen d'obtenir un résultat correct sans. changer les fonctions de a et b

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

répondre à tous(6)
阿神

Je suis désolé de vous dire que le nœud est explicitement asynchrone, donc si vous changez une fonction de synchrone à asynchrone, alors les fonctions qui en dépendent doivent également être modifiées. C'est en effet un casse-tête lors du refactoring, mais il faut quand même le faire. supportons-le. Changeons-le.

Le refactoring comme fibjs, qui ne nécessite pas le mot-clé async, est très simple. Si vous modifiez c, vous n'avez pas besoin de changer a et b, car l'asynchronie implicite ne nécessite pas que vous l'indiquiez.

洪涛

Je ne comprends toujours pas assez bien Promise. Il n'est pas nécessaire de changer b()a() ici.

Pour capturer cette promesse dans la fonction c,只需要返回一个promise对象,经过函数b的时候,直接同步返回这个Promise对象,不需要改动函数b使其为异步函数,因为异步操作是在函数c中,b中只进行了同步操作。此时需要在函数a, le code peut être modifié par ceci

function promiseC(m) {
    return new Promise((resolve, reject) => {
        setTimeout(function () {
            m = m + 1;
            resolve(m);
        }, 1000)
    })
}


function c(m) {
    m = promiseC(m);
    return m;
}

function b(m) {
    m = m + 1;
    return c(m);
}
function a() {
    let m = 0;
    return b(m);
}

p.then(function(a){
    console.log(a)
})

Donc, si cette fonction a(),b()ne gère pas la valeur de retour des opérations asynchrones, pourquoi devrait-elle être remplacée par une fonction Async ?

扔个三星炸死你

Vous pouvez essayer http://fibjs.org/docs/manual/... et le convertir directement en synchronisation

滿天的星座

Je dois dire que j'ai regardé l'écran et fait de nombreux brouillons, mais à la fin j'ai échoué.

Je ne vois aucun moyen de bloquer la fonction actuelle dans js tout en exécutant la résolution de la promesse à temps. L'idée de l'échec est la suivante

.
c_result=null
c=async (m)=>{return m+1}
c_sync = (m)=>{
    let n=0
        pc=c(m).then((m)=>{c_result=m})
    while(c_result===null && n++<100){}
    return c_result
}
b=(m)=>{return c_sync(m+1)}
a=()=>{return b(0)}
a()

Le problème est que bien que while(c_result===null && n++<100){}阻塞了函数c_sync, 但是也阻止了.thenle rappel soit exécuté. En raison du mécanisme asynchrone à thread unique, lorsqu'un certain rappel est déclenché, si le thread est occupé, le rappel ne peut pas sauter dans la file d'attente, ce qui empêche c_result de faire quoi que ce soit. pendant l'exécution de la boucle. Attribué à la variable m, il n'y a aucun moyen de sortir de la boucle

.

Mais je pense que cette question est très intéressante. J'ai trouvé un article connexe. L'auteur a résolu le problème du blocage local via une bibliothèque binaire externe.

http://blog.csdn.net/xingqili...

Ma compréhension est la suivante :
Sur la base de la boucle d'événements du moteur js lui-même, nous ne pouvons pas bloquer un certain bloc. Parce que pour le code js, la boucle d'événements du moteur est en bas. Mais pour les modules binaires externes, il peut se bloquer. Et assurez-vous que la boucle d'événements du moteur js traverse complètement la file d'attente des événements à chaque fois ---- pour garantir que les nouveaux événements dans le moteur js peuvent être traités pendant sa propre période de blocage.

巴扎黑

La promesse de sortie Let a() peut en effet résoudre le problème que j'ai mentionné
Mais lorsque j'ai réellement modifié le code, j'ai découvert que la structure de la plupart du code n'était pas comme mon problème ci-dessus
mais la structure nouvellement ajoutée ci-dessous

function c(m) {
    m = m + 1;
    return m;
}
function b(m) {
    m = m + 1;
    let n = c(m)
    n = n + 1
    return n;
}
function a(){
    let m = 0;
    let k = b(m);
    k = k + 1;
    return k;
}
世界只因有你

Avec tout le respect que je vous dois, vous n'avez pas une compréhension approfondie du mécanisme de boucle d'événements et du module de base d'événements de node.js.
promise et aysnc/await sont en effet les éléments dominants dans la gestion du contrôle de processus asynchrone aujourd'hui, mais cela ne signifie pas que cela ne peut pas être fait sans eux. Des problèmes aussi simples peuvent être traités via la méthode événementielle.

const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();

myEmitter.on('a', (m) => {
    console.log('a -> b');
    myEmitter.emit('b', m+1);
});
myEmitter.on('b', (m) => {
    console.log('b -> c');
    myEmitter.emit('c', m+1);
});
myEmitter.on('c', (m) => {
    console.log('result', m);
});
myEmitter.emit('a', 0);
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!