2016-10-03 2 views
-1

を返さない、私は私の滝にstuckedています:fs.readFileは、多くの研究とテストの後、データ

async.waterfall([ 
    //first 5 functions are going fine and passing expected vars to the next function the function below is the pb 
    // eg adSetId var comes just fine from previous function 
    function(imgName,adsetId,callback) { 
    fs.readFile('./shopifyImages/'+imgName , 'base64' ,function(err,imgData) { 
     callback(null,imgData,adsetId); 
    }); 
    } 
]); 

imgDataは常に空の値を返しています。 関数からのエラーはありません。また、その滝の作業には適切です(fs.readFileが期待通りに機能します)。console.logには空のimgDataもあります。

FULL CODE

async.waterfall([ 
    //GET AD ACCOUNT FOR USER 
    function(callback) { 
     var sqlAd_act = vsprintf('select * from fbTokens where userId=%s', [roomIDCook.userId]); 
     connection.query(sqlAd_act).then(function(rows) { 
      //console.log('rows '+rows); 
      callback(null, rows[0].ad_act); 
     }); 
    }, 
    //SET CAMPAIGN 
    function(ad_act, callback) { 
     fb.api('/act_' + ad_act + '/campaigns', 'post', { 
      'status': 'PAUSED', 
      'name': 'GENIE 2' 
     }, function(data) { 
      //console.log('data: ' + util.inspect(data)) 
      callback(null, data.id, ad_act); 
     }); 
    }, 
    //SET ADSET 
    function(campaignId, ad_act, callback) { 
     console.log('ad account ' + ad_act); 
     console.log('campaignId ' + campaignId); 
     fb.api('/act_' + ad_act + '/adsets', 'post', { 
      'daily_budget': 500, 
      'start_time': '2017-02-18T20:11:25+0000', 
      'end_time': '2017-03-25T20:11:25+0000', 
      'name': 'new adset', 
      'optimization_goal': 'LINK_CLICKS', 
      'objective': 'LINK_CLICKS', 
      'campaign_id': campaignId, 
      'status': 'PAUSED', 
      'billing_event': 'LINK_CLICKS', 
      'bid_amount': 2, 
      'targeting': { 
       "geo_locations": { 
        "countries": ["US"] 
       }, 
       "publisher_platforms": ["facebook"] 
      } 
     }, 
     function(res) { 
      if (!res || res.error) { 
       console.log(!res ? 'error occurred' : util.inspect(res.error)); 
       return; 
      } 
      //console.log(util.inspect(res)); 
      callback(null, res.id) 
     }); 
    }, 
    // CREATE THE AD FOR THE ADSET 
    function(adsetId, callback) { 
     // set img 
     var imgUri = 'https://cdn.shopify.com/s/files/1/1336/5343/products/9_b75df43c-1660-4aeb-89b7-418df1a9853c_1024x1024.jpg?v=1466985077'; 
     var DOWNLOAD_DIR = 'shopifyImages/'; 
     var imgName = 'TEST2.jpg'; 
     console.log('adsetId ' + adsetId); 
     // download img 
     request.head(imgUri, function(err, res, body) { 
      console.log('content-type:', res.headers['content-type']); 
      console.log('content-length:', res.headers['content-length']); 
      request(imgUri).pipe(fs.createWriteStream(DOWNLOAD_DIR + imgName)); 
      console.log('adsetId ' + adsetId); 
      callback(null, imgName, adsetId); 
     }); 
     // read img for facebook 
    }, 
    function(imgName, adsetId, callback) { 
     fs.readFile('./shopifyImages/' + imgName, 'base64', function(err, imgData) { 
      console.log(util.inspect(err)); 
      console.log(util.inspect(imgData)); 
      callback(null, imgData, adsetId); 
     }); 
    }, 
    function(imgData, adsetId, callback) { 
     console.log(imgData); 
     console.log('adsetId ' + adsetId); 
    } 
], function(error, c) { 
    console.log(c); 
}); 
+0

以前の関数からのコールバックを表示できますか?あなたは有効な 'imgName'を渡していますか? – DrakaSAN

+0

私はあなたが 'imgName'がどのように設定されているか、この関数と他のものとで異なる可能性があることを含めて、ここでもっと多くの実行コンテキストを表示しなければならないと思います。十分な情報がここに表示されていません。 – jfriend00

+0

こんにちは、ありがとうfrの答え、はい、かなり確かにimgNameは、ファイル名 "ハードコード" var名の代わりに試してみました。また、不正なファイル名で試してみたところ、期待どおりにエラーが発生しました。 – direxit

答えて

1

ストリームは非同期であるので、あなたはタイミングの問題があります。

request(imgUri).pipe(fs.createWriteStream(DOWNLOAD_DIR + imgName)); 
callback(null, imgName, adsetId); 

しかし、ストリームが callback()を呼び出して、あなたが既に存在する imgNameファイルを期待して次のステップに進む前に完了するために、あなたは待っていない:あなたはこれをやっています。したがって、新しく作成されたファイルが書き込まれる前に、そのファイルを読み込もうとしています。

ストリームのイベントハンドラを登録して、ストリームの書き込みが完了したことを知ってから、callback(null, imgName, adsetId)を呼び出して次のステップに進む必要があります。

私はこれを行うには、よりエレガントな方法があるかもしれないので、ストリームの達人ないんだけど、ここでは一つの解決策だ:FYI

// CREATE THE AD FOR THE ADSET 
function(adsetId, callback) { 
    // set img 
    var imgUri = 'https://cdn.shopify.com/s/files/1/1336/5343/products/9_b75df43c-1660-4aeb-89b7-418df1a9853c_1024x1024.jpg?v=1466985077'; 
    var DOWNLOAD_DIR = 'shopifyImages/'; 
    var imgName = 'TEST2.jpg'; 
    console.log('adsetId ' + adsetId); 
    // download img 
    request.head(imgUri, function(err, res, body) { 
     console.log('content-type:', res.headers['content-type']); 
     console.log('content-length:', res.headers['content-length']); 
     console.log('adsetId ' + adsetId); 
     var outputStream = fs.createWriteStream(DOWNLOAD_DIR + imgName); 
     outputStream.on('finish', function() { 
      callback(null, imgName, adsetId); 
     }); 
     outputStream.on('error', function(err) { 
      callback(err); 
     }); 
     request(imgUri).pipe(outputStream); 
    }); 

、それがワンステップでファイルにデータを書き込むために、概念的に奇妙だと次のステップでそれをメモリに読み戻します。非常に非効率的です。最初にメモリに読み込んだり、それをファイルに残しておきたいのであれば、それをファイルに書きますが、書き込んだデータをメモリに残しておくのはなぜですか?

+0

@direxit:その隣にある緑色のマークをクリックすると、正しい答えとしてマークすることができます。あなたはまたそれのための担当者を受け取ります。 – DrakaSAN

+0

修正プログラムのコード例を追加しました。 – jfriend00

+0

@ jfriend00あなたは上司です! *****、そのストリーム未完成のものだった、そして、はい私は1つのステップを避けることができます:) – direxit

関連する問題