2016-10-18 7 views
2

Ich habe diese Funktion hier:Warum erhalte ich einen Segmentierungsfehler in Node.js?

function createInsta(email, userid) { 
    if (!fs.existsSync('users/' + email + '/' + userid)) { 
    fs.mkdir('users/' + email + '/' + userid) 
    fs.writeFileSync(('users/' + email + '/' + userid + '/instagram.json'), fs.readFileSync("data/data.json", "utf-8")) 
    console.log("insta folder created"); 
    } 
    console.log("Initializing Data") 
    var data = fs.readFileSync('users/' + email + '/' + userid + '/instagram.json', "utf-8") 
    data = JSON.parse(data); 
    var result; 
    request(("https://instagram.com/" + userid + "/?__a=1"), function(error, response, body) { 
    var res = JSON.parse(body); 
    result = res.user.followed_by.count 
    if (error) { 
     console.log(err) 
    } 
    }) 
    while (result === undefined) { 
    deasync.sleep(100) 
    } 
    data.STARTING_COUNTS[0].DAY = result; 
    data.STARTING_COUNTS[0].WEEK = result; 
    data.STARTING_COUNTS[0].MONTH = result; 

} 

direkt nach der Konsole druckt outs Initializing Data, sagt die Konsole Segmentation fault

ich keine Ahnung, warum das so ist, nicht mein Code scheinen, wie etwas so dazu führen könnte, ein Fehler.

Irgendwelche Zeiger? Danke

+0

"Alle Zeiger" - Wortspiel beabsichtigt? – joews

+0

Ich mag nicht das Aussehen von -> 'while (result === undefined) {deasync.sleep (100)}' Und warum wird es benötigt? – Keith

+0

@Keith Ich benutzte es als eine einfache und schnelle hack um das async-Modell von Nodejs für diese Funktion, ich habe es in anderen Funktionen ohne Problem verwendet, bezweifle ich, dass es die Ursache der segfault – Vikaton

Antwort

2

Wie versprochen (entschuldigen Sie das Wortspiel), wird hier begonnen, Ihren Code in Versprechen/erwarten zu konvertieren.

Dies ist ein bisschen ein Anfang der macht Ihren Code in Versprechungen zu verwenden, es ist mehr Fehlerüberprüfung erforderlich usw., aber ich habe absichtlich so wenig zum Code für jetzt auch Änderungen zeigen, und wir können refactor wie wir gehen auf.

z. alles, was fs.existsSync usw. machen will, macht Versprechen, damit wir alle Sync-Sachen loswerden können. Deine node.js App wird dich dafür lieben.

Später können wir mehr tun. Promise ist in Browser/Node in Ordnung, aber ich finde auch eine Promise-Lib kann die Dinge einfacher machen, würde ich empfehlen, bluebird ->http://bluebirdjs.com/docs/getting-started.html Es lohnt sich auch dort zu lesen, hat Bluebird einige nützliche Funktionen wie Promisify machen Ihr fs.func ist einfacher.

Also ich denke, das sollte für jetzt tun, und wir werden später einen anderen Refactor machen.

//lets mark this function as async.. 
 
async function createInsta(email, userid) { 
 
    return new Promise(function (resolve, reject) { 
 
    if (!fs.existsSync('users/' + email + '/' + userid)) { 
 
     fs.mkdir('users/' + email + '/' + userid) 
 
     fs.writeFileSync(('users/' + email + '/' + userid + '/instagram.json'), fs.readFileSync("data/data.json", "utf-8")) 
 
     console.log("insta folder created"); 
 
    } 
 
    console.log("Initializing Data") 
 
    var data = fs.readFileSync('users/' + email + '/' + userid + '/instagram.json', "utf-8") 
 
    data = JSON.parse(data);  
 
    request(("https://instagram.com/" + userid + "/?__a=1"), function(error, response, body) { 
 
     if (error) { 
 
     console.log(err) 
 
     return reject(error); 
 
     } 
 
     var res = JSON.parse(body); 
 
     var result = res.user.followed_by.count 
 
     data.STARTING_COUNTS[0].DAY = result; 
 
     data.STARTING_COUNTS[0].WEEK = result; 
 
     data.STARTING_COUNTS[0].MONTH = result; 
 
     resolve(data); //i'm assuming data is what your wanting to return 
 
    }) 
 
    }); 
 
} 
 

 
//to be able to use await our function also needs to be async 
 
async function run() { 
 
var data = await createInsta('[email protected]'); 
 
}

+0

danke! Ich habe tatsächlich in Bluebird geschaut, bevor ich das gelesen habe, und meinen Callback-Code in Versprechungen umgestaltet: https://gist.github.com/Vikonon/18cf0891e8c00ff2d7cbfdbfdca83e26 Wie auch immer, dein Bild sieht prägnanter aus, ist dein Code besser als der promitierte? – Vikaton

+0

Promisified ist ein Begriff, der von Bluebird verwendet wird, um Knoten-Callbacks in Promise-basierte Funktionen umzuwandeln. Ich habe einen neuen Beitrag hinzugefügt, der dies in Aktion zeigt. – Keith

1

Ok, lässt unsere letzten Beitrag Refactoring.

Es gab nur einen Grund, warum wir den new Promise()-Konstruktor verwenden, und zwar deshalb, weil die Anfrage Async ist. Tatsächlich habe ich einen kleinen Fehler gemacht, da einige Fehler nicht richtig behandelt werden. Was ich hätte tun sollen, ist das Verschieben der new Promise() direkt vor der Anfrage.

Nun eine großartige Sache über Promises ist, dass sich der Fehler in der Kette ausbreitet, in unserem Beispiel haben wir eine console.log() in unserem Anfrageobjekt. Was ist schön, dass alle nicht behandelten Fehler an einem Ort behandelt werden. In diesem Beispiel scheint die Funktion run() ein schöner Ort zu sein.

Wenn Sie jetzt Ihre createInsta-Funktion betrachten, würden Sie denken, dass sie alle sync-Funktion verwendet, aber abgesehen von existSync ist alles andere async. Wie in den Kommentaren erwähnt, möchte existSync wirklich entfernen. Stattdessen erstellen Sie einfach das Verzeichnis und fangen Sie den Fehler in einem Versuch fangen, oder noch besser eine Dienstprogrammfunktion sagen namens tryMkDir, das tut dies (Versprechen basiert natürlich).

Eine letzte Notiz, erwarten/async ist ein ziemlich neues Javascript, ich denke, es ist ES7, und ich glaube nicht, dass es noch nicht abgeschlossen ist. Aber du kannst es jetzt benutzen, indem du etwas wie Babel benutzt.

//lets make a Promise based request. 
 
//There is an NPM module that would do this and more 
 
//but this is a good example of making existing callback 
 
//functions into a Promise. 
 

 
async function promRequest(url) { 
 
    return new Promise(function(resolve, reject) { 
 
    request(url, function(error, response, body) { 
 
     if (error) return reject(error); 
 
     //promises can only return one thing 
 
     //so use an object literal to return more 
 
     resolve({ 
 
     response:response, 
 
     body: body 
 
     }); 
 
    }); 
 
    }); 
 
} 
 

 
//lets also promisify some Node stuff. 
 
var Promise = require('bluebird'); 
 

 
//there is a promisifyall, but I like to be 
 
//specific about what I promisify. 
 
var fsWriteFile = Promise.promisify(fs.writeFile), 
 
    fsReadFile = Promise.promisify(fs.readFile), 
 
    fsMkdir = Promise.promisify(fs.mkdir); 
 

 

 
//because promRequest is already a promise 
 
//we can now get rid of the new Promise contructor here. 
 
//The only part of this function that is now async 
 
//is existsSync, the exists() in node is depreciated 
 
//due to potential race conditions, really this 
 
//should be altered to just try and create dirctory 
 
//and catch error if exists. 
 
async function createInsta(email, userid) { 
 
    if (!fs.existsSync('users/' + email + '/' + userid)) { 
 
    await fsMkdir('users/' + email + '/' + userid); 
 
    await fsWriteFile(('users/' + email + '/' + userid + '/instagram.json'), await fsReadFile("data/data.json", "utf-8")); 
 
    console.log("insta folder created"); 
 
    } 
 
    console.log("Initializing Data") 
 
    var data = await fsReadFile('users/' + email + '/' + userid + '/instagram.json', "utf-8") 
 
    data = JSON.parse(data);  
 
    var res = JSON.parse(
 
    await promRequest("https://instagram.com/" + userid + "/?__a=1").body); 
 
    var result = res.user.followed_by.count 
 
    data.STARTING_COUNTS[0].DAY = result; 
 
    data.STARTING_COUNTS[0].WEEK = result; 
 
    data.STARTING_COUNTS[0].MONTH = result; 
 
    return data; 
 
} 
 

 
//to be able to use await our function also needs to be async 
 
async function run() { 
 
    //lets catch all unahandled errors here. 
 
    try { 
 
    var data = await createInsta('[email protected]'); 
 
    } catch (e) { 
 
    //fantasic any error's can now be logged 
 
    //eg. fsMkdir might have failed and it's still 
 
    //going to be logged here.. 
 
    console.log(e); 
 
    } 
 
}

+0

Vielen Dank! – Vikaton

Verwandte Themen