範囲

2017-05-01 12 views
0

私は範囲

function parseLink(link) { 
    var product; 
    request(link, function (error, response, body) { 
     if (!error && response.statusCode == 200) { 
      var $ = cheerio.load(body); 

      // title 
      var title = $('h1').text(); 
      if (!title) 
       var title = $('title').text(); 

      var description = $('meta[name="description"]').attr('content'); 

      product = new Product(link.trim(), title.trim(), description.trim()); 
     } 
    }); 
    console.log(product); 
    return product; 
} 

この機能を持っていると私はにconsole.log(製品)要求コールの外側を行うときに、私が持っている理由を私は理解していません未定義でも、私の商品を見ることができます。

私はJavaScriptのスコープについてたくさんのことを学びますが、私は理解しません。私はの製品をトップファンクションに定義しました。 私はこの変数を別の関数で取得するために返す必要があります。リクエスト内でリターンを返す場合は、もちろん未定義ですので、外出する必要があります。

+0

あなたがトップ機能であなたの変数 'product'に値と'にconsole.logを割り当てていなかったので() '要求機能からの割り当てを待っていません。 – hhh

+0

[非同期呼び出しから応答を返すにはどうすればよいですか?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) –

+0

'request'関数はどこに定義されていますか? –

答えて

0

javascriptは実行されません。 cまたはphpのようなコードで、前のコードの準備が整ったときに次のコード行が実行されることを確認できます。あなたのrequest機能は準備ができる前に

console.log(product); 
return product; 

2行はほとんど実行されているので、あなたのケースではrequestは非同期関数です。その場合は、parseLink関数から値を返すことはできません。

  1. 使用の約束:このような

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise

  • コールバックを使用あなたはここでは2つの可能性が持っている

    function parseLink(link, callback) { 
        var product; 
        request(link, function (error, response, body) { 
         if (!error && response.statusCode == 200) { 
          var $ = cheerio.load(body); 
    
          // title 
          var title = $('h1').text(); 
          if (!title) 
           var title = $('title').text(); 
    
          var description = $('meta[name="description"]').attr('content'); 
    
          product = new Product(link.trim(), title.trim(), description.trim()); 
          callback(product); 
         } 
        }); 
    } 
    

    を、あなたのようなコードを実行します

    parseLink('http://...', function(product) { /* do something with the product */ }); 
    

    PSは:コールバックの使用は、芋多くの方が簡単ですが、あなたはforループでそれを実行する場合、いくつかのケースでは、あなたは

  • +0

    ありがとう、私は別の関数からparseLinkを呼び出します。 'var linkParsed = parseLink(data [0]);' –

    +0

    私が書いたように、非同期関数から直接値を返すことはできません。私の答えの最後に、コールバック関数を使った例があります。ミゲルも約束のある例を提供 –

    +0

    Cについてはどうですか?呼び出しの引数として関数へのポインタを渡すことができ、この呼び出しが返すまでに関数が呼び出されたかどうかはわかりません。 – bipll

    0

    requestはそう非同期呼び出し、この手順で例のスコープを分離することができます現在のコールスタックが終了すると実行されるイベントキューにプッシュされます。 console.logundefinedを出力します。これは、割り当てられていない変数のデフォルト値です。

    非同期呼び出しから値を返す必要がある場合は、コールバックまたは約束を使用する必要があります。ここで使用した例ですPromise

    function parseLink(link) { 
        return new Promise((resolve, reject) => { 
        request(link, function(error, response, body) { 
         if (error) return reject(error); 
    
         if (response.statusCode !== 200) { 
         return reject(new Error('Not OK')); 
         } 
    
         var $ = cheerio.load(body); 
    
         var title = $('h1').text() || $('title').text(); 
         var description = $('meta[name="description"]').attr('content'); 
         var product = new Product(link.trim(), title.trim(), description.trim()); 
    
         resolve(product); 
        }); 
        }); 
    } 
    
    parseLink('http://example.com') 
        .then(product => { 
        console.log(product); 
        }) 
        .catch(error => { 
        console.error(error); 
        }); 
    
    +0

    ありがとうございますが、私は 'var linkParsed = parseLink(data [0]);'のような値を返す必要があります –

    +0

    @Tech同期リクエストを行う必要がありますが、非常に推奨されていません。https://www.npmjs.com/package/sync-request –