2016-10-18 13 views
2

私は右ここにこの機能を持っている:右コンソールプリントアウトした後Node.jsでSegmentationフォルトが発生するのはなぜですか?

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; 

} 

Initializing Data、コンソールは、私は何も、このような原因となりますように、これは、私のコードは思えませんされている理由見当もつかないSegmentation fault

語りますエラー。

任意のポインタ?ありがとう

+0

"任意のポインタ" - しゃれ意図? – joews

+0

私は - > 'の外観が好きではありません(結果=未定義){deasync.sleep(100)}'それはなぜ必要なのですか? – Keith

+0

@Keith私はこの関数のnodejsの非同期モデルをシンプルで素早くハッキングして使用しましたが、他の関数でも問題なく使用しましたが、segfaultの原因は疑問です – Vikaton

答えて

2

約束どおり(ここで言い訳)、コードをPromise/awaitに変換しようとしています。

これは、約束事を使用してコードを作成するようなものです。エラーチェックなどが必要ですが、私は故意にコードを少し変更して変更を表示しました。に。

例えば、すべてのfs.existsSyncなど、約束をしたいので、私たちはすべての同期のものを取り除くことができます。あなたのnode.jsアプリケーションがあなたを愛してくれるでしょう。

これ以降、さらに対応できます。プロミスはブラウザ/ノードに組み込まれていますが、私はプロミスのlibが物事をより簡単にすることができることも知っています、私はブルーバードを提案します - >http://bluebirdjs.com/docs/getting-started.htmlそれは良い読書をする価値があるかもしれません、ブルーバードは、 fs.funcの方が簡単です。

これは今のところやるべきことだと思います。後で別のリファクタリングを行います。

//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

ありがとう!私は実際にこれを読む前にブルーバードを調べて、私のコールバックコードを約束にリファクタリングしました:https://gist.github.com/Vikaton/18cf0891e8c00ff2d7cbfdbfdca83e26あなたのコードはもっと簡潔に見えますが、あなたのコードは有名なものよりも優れていますか? – Vikaton

+0

Promisifiedは、ノードコールバックをPromiseベースの関数に変換するためにBluebirdが使用する用語です。これを実際に示す新しい投稿を追加しました。 – Keith

1

[OK]を、私たちの最後のポストをリファクタリングすることができます。

私たちがnew Promise()コンストラクタを使用する理由は1つだけでした。これはリクエストがAsyncであるためです。実際、私はいくつかのエラーが正しい方法で処理されないので、実際には少し間違いを犯しました。私がしなければならないのは、要求の直前にnew Promise()を移動することです。

Promisesの大きな点の1つは、エラーがチェーンを伝播するということです。これまでの例では、requestオブジェクト内にconsole.log()があります。いいのは、未処理のエラーがすべて1か所で処理されることです。この例では、run()関数は素晴らしい場所のようです。

ここでcreateInsta関数を見ると、すべての同期関数を使用していると思うでしょうが、実際にはexistsSyncとは別のものはすべてasyncです。コメントの中で述べたように、existSyncはとにかく削除したいと思っています。代わりに、単にディレクトリを作成し、try catchでエラーをキャッチするか、またはこれを行うtryMkDirというユーティリティ関数を作成するのが良いでしょう。:)

最後に、await/asyncは次のとおりですかなり新しいjavascript、私はそれがES7だと思うし、まだ完成したとは思わない。しかし、あなたは今、バベルのようなものを使ってそれを使うことができます。

//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

ありがとう! – Vikaton

関連する問題