2016-11-21 24 views
0

私は概念を約束する新しいですし、周りに私の頭をラップしようとしているが、今I``が混乱していますここどのように約束の問題を解決するには?

const request = require("request"); 
const cheerio = require("cheerio"); 
const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; 
var url = require("url"); 


module.exports = { 

    resturant: resturant, 

}; 


var resturanttables = []; 

function resturant(url, day) { 

    return new Promise(function(resolve, reject) { 
     request(url, function(error, response, html) { 

      if (error) { 
       return reject(error); 

      } else if (response.statusCode !== 200) { 

       return reject("Something is wrong! CINEMA") 

      } 
      httplogin("zeke", "coys", url, day); 
      console.log(resturanttables, "i am here"); 

      resolve(resturanttables); 

     }); 



    }); 
} 

function httpafterlogin(url, cookie, day) { 

    request.get({ 
      headers: { 
       'content-type': 'text/html', 
       'Cookie': cookie 
      }, 
      url: url, 
     }, 

     function(error, response, body) { 



      console.log(day) 
      var $ = cheerio.load(body); 

      if (day === "Friday") { 
       $(".WordSection2 p span ").each(function(li) { 
        // console.log(day, $(this).text()) 
        resturanttables.push($(this).text()); 

        console.log(resturanttables, "nside"); 
       }); 

      } else if (day === "Saturday") { 
       $(".WordSection4 p span").each(function(li) { 

        resturanttables.push($(this).text()) 
       }); 

      } else { 
       $(".WordSection6 p span").each(function(li) { 

        resturanttables.push($(this).text()) 


       }); 

      } 

     }); 

} 

function httplogin(username, password, urls, day) { 

    request.post({ 
     headers: { 
      'content-type': 'application/x-www-form-urlencoded' 

     }, 
     url: urls, 
     form: { 
      "username": username, 
      "password": password 


     } 
    }, function(error, response, body) { 
     var cookie = response.caseless.dict['set-cookie'][0]; 
     var location = response; 

     console.log(response.statusCode); 
     cookie = cookie.substring(0, cookie.indexOf(';')); 

     // httpafterlogin('http://vhost3.lnu.se:20080/dinner/'+response.headers.location, cookie); 
     var newurls = url.resolve(urls, response.headers.location) 
     httpafterlogin(newurls, cookie, day); 

     // console.log(response.headers, "jdjdjjdjdjjdjdjdjjdjjdjdj") 

    }); 

} 

、その後、私は、問題は、それが返すことです

loadPage.resturant("http://vhost3.lnu.se:20080/dinner/login", "Friday").then(function(data) { 
    console.log(data, "did it work now ") 
}) 

関数を呼び出します空の配列。しかし、私は、afterlogin関数でconsole.logを調べようとしたところ、実際に配列が埋め込まれているのがわかりましたが、約束が解決された後にコードが実行されます。 短期間:ログイン機能が完了するまでデータを送信しないことをレストランで約束して解決する方法を教えてください。

言い換えれば、埋め込み配列にafterlogin関数の情報をどのように取得できますか?

+0

私は何か間違っているとは思わない...多分あなたは少しのコードや何かを残しましたか? 'data'にあなたの配列が含まれていれば、すべてが良いです。 –

+0

'httpafterlogin'は、他のものと同じ約束設定を必要とします。 –

+0

しかし、Kevin Bさんはどのように試してみましたが、うまくいきませんでした。 – Alex

答えて

0
を完了するまで、 resolve(restautanttables)を含むブロックが呼び出され得ることはありません

コード全体で約束を使用すると、コードを簡略化することができます要求パッケージの代わりにrequest-promiseパッケージ。すべての要求は約束となり、コードは読みやすく、管理しやすくなります。

const rp = require("request-promise"); 
const cheerio = require("cheerio"); 
const url = require("url"); 

function resturant(url, day) { 
    rp(url) 
    .then(function(){ 
     // URL returned a 200 response 
     // so attempt to perform login 
     httplogin("zeke", "coys", url, day) 
     .then(function (data) { 
      // Promise is resolved here 
      return data; 
     }); 
    }) 
    .catch(function(error){ 
     // just throwing the error 
     throw error; 
    }); 
} 

function httplogin(username, password, urls, day) { 
    var options = { 
    headers: { 
     "content-type": "application/x-www-form-urlencoded" 
    }, 
    uri: urls, 
    form: { 
     username: username, 
     password: password 
    }, 
    method: "POST", 
    resolveWithFullResponse: true 
    }; 
    rp(options) 
    .then(function (response) { 
     // POST succeeded 
     // grab the cookie 
     var cookie = response.caseless.dict['set-cookie'][0] 
          .substring(0, cookie.indexOf(';')); 
     // get new url string 
     var newurls = url.resolve(urls, response.headers.location); 

     httpafterlogin(newurls, cookie, day) 
     .then(function (tables) { 
      return tables; 
     }) 
     .catch(function (error) { 
     // just throwing the error 
     throw error; 
     }); 

    }) 
    .catch(function (error) { 
     // Login failure 
     // just throwing the error 
     throw error; 
    }); 
} 

function httpafterlogin(url, cookie, day) { 
    var options = { 
    headers: { 
     "content-type": "text/html", 
     "Cookie": cookie 
    }, 
    uri: url, 
    transform: function (body) { 
     return cheerio.load(body); 
    } 
    }; 
    rp(options) 
    .then(function ($) { 
     // body has been transformed and 
     // can now be processed with jQuery 

     // initialise the tables array 
     var tables = []; 

     // DRY code 
     // set default selector 
     var selector = ".WordSection6 p span"; 
     // change the selector for Friday/Saturday 
     if (day === "Friday") { 
     selector = ".WordSection2 p span "; 
     } else if (day === "Saturday") { 
     selector = ".WordSection4 p span"; 
     } 
     // process the selected section 
     $(selector).each(function(li) { 
     tables.push($(this).text()) 
     }); 

     // crawling complete 
     return tables; 
    }) 
    .catch(function (error) { 
     // Crawling failure 
     // just throwing the error 
     throw error; 
    }); 
} 
+0

あなたは*どこでも*約束を返すのを忘れました。 – Bergi

+0

'.then(function(data){return data;})'と '.catch(function(error){throw error;});'は無意味です。 。特に、読みやすくメンテナンス可能なコードが必要な場合。 – Bergi

0

あなたはログインが完了する前に、あなたはあなたのhttplogin関数がコールバックを取ると、このようにそれを実行して確認する必要がありますいずれかの約束が解決を取得したくない場合は、次の

httplogin("zeke", "coys", url, day, function (err) { 
    if (err) { 
    reject(err); 
    } else { 
    resolve(resturanttables); 
    } 
}); 

またはそれを返すように約束して実行してください:

httplogin("zeke", "coys", url, day).then(function() { 
    resolve(resturanttables); 
}).catch(function (err) { 
    reject(err); 
}); 

約束でそれを行う方法はもっとたくさんありますが、これは最も簡単な方法です。

どちらの場合でも、httplogin関数は、引数として受け取ったコールバックをコールするか、返される約束を解決するかのいずれかによってシグナルを補完する必要があります。約束を返すために

+0

実際にそれが問題で私は約束を約束することができますか?私はどのように私のhttp関数をラップすることができますか?あなたが私にどのように試してみたかを私に見せることができればそれは本当にうれしいです – Alex

1

書き換えhttploginhttpafterlogin:RSPが提案のように

function httpafterlogin (url, cookie, day) { 
    return new Promise(function (resolve, reject) { 
     request.get({ 
      headers: { 
       'content-type': 'text/html', 
       'Cookie': cookie 
      }, 
      url: url 
     }, function (error, response, body) { 
      if (error) { 
       reject(error); 
      } else { 
       resolve(body); 
      } 
     }); 
    }).then(function (body) { 
     console.log(day); 
     var $ = cheerio.load(body); 

     if (day === "Friday") { 
      $(".WordSection2 p span").each(function (li) { 
       // console.log(day, $(this).text()); 
       resturanttables.push($(this).text()); 
       console.log(resturanttables, "nside"); 
      }); 
     } else if (day === "Saturday") { 
      $(".WordSection4 p span").each(function (li) { 
       resturanttables.push($(this).text()); 
      }); 
     } else { 
      $(".WordSection6 p span").each(function(li) { 
       resturanttables.push($(this).text()); 
      }); 
     } 
    }); 
} 


function httplogin(username, password, urls, day) { 
    return new Promise(function (resolve, reject) { 
     request.post({ 
      headers: { 
       'content-type': 'application/x-www-form-urlencoded' 
      }, 
      url: urls, 
      form: { 
       "username": username, 
       "password": password 
      } 
     }, function(error, response, body) { 
      if (error) { 
       reject(error); 
      } else { 
       resolve(response); 
      } 
     }); 
    }).then(function (response) { 

     var cookie = response.caseless.dict['set-cookie'][0]; 
     var location = response; 

     console.log(response.statusCode); 
     cookie = cookie.substring(0, cookie.indexOf(';')); 

     var newurls = url.resolve(urls, response.headers.location) 
     return httpafterlogin(newurls, cookie, day); 
    }); 
} 

その後、.thenを使用します。

function resturant(url, day) { 

    return new Promise(function(resolve, reject) { 
     request(url, function(error, response, html) { 
      if (error) { 
       return reject(error); 
      } else { 
       resolve(response); 
      } 
     }) 
    }).then(function (response) { 
     if (response.statusCode !== 200) { 
      throw new Error("Something is wrong! CINEMA");  
     } 
     return httplogin("zeke", "coys", url, day) 
    }).then(function() { 
     console.log(resturanttables, "i am here"); 
     return resturanttables; 
    }); 
} 

この方法をhttplogin

+0

最初の文ははいですが、['Promise'コンストラクタ反パターンを避けてください](http://stackoverflow.com/ q/23803743/1048572)! – Bergi

+0

これは良いですか?もし私が説明を理解したいと思うなら、私は学びたいと思いますが、検索結果には、すでに約束を返している関数の余分なラッピングが含まれているようです(この例ではコールバックスタイルの関数ではなく) – thedarklord47

+0

これは、私の理解に反パターンの否定) – thedarklord47

関連する問題