2016-11-21 37 views
0

Ich bin neue Konzepte zu versprechen und zu versuchen, meinen Kopf herum zu wickeln, aber jetzt I`` ist hier verwirrtWie löst man ein Versprechen?

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") 

    }); 

} 

und ich rufe dann die Funktion

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

das Problem ist, dass es das gibt leeres Array. Aber als ich versuchte zu überprüfen und console.log in der afterlogin Funktion und ich konnte sehen, dass das Array tatsächlich gefüllt war, aber dieser Code läuft, nachdem das Versprechen gelöst wurde. Kurz gesagt: Wie kann ich die Auflösung im Restaurant versprechen, die Daten nicht zu senden, bis die Login-Funktion abgeschlossen ist?

mit anderen worten wie kann ich das gefüllte array mit informationen von afterlogin funtion bekommen?

+0

Ich sehe nichts falsch ... vielleicht haben Sie ein wenig Code oder etwas weggelassen? Wenn 'data' Ihr Array enthält, dann ist alles gut. –

+0

'httpafterlogin' benötigt das gleiche Setup wie das andere. –

+0

Aber wie Kevin B ich versuchte, aber es funktioniert nicht – Alex

Antwort

0

Verwenden Sie Versprechen in Ihrem Code - Sie können Ihren Code mit vereinfachen das Paket request-promise anstelle des Anfragepakets. Alle Anfragen werden zu Versprechen und der Code ist leichter zu lesen und zu pflegen.

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

Sie haben vergessen, die Versprechen * überall * zurückzugeben. – Bergi

+0

Dinge wie '.then (function (data) {return data;})' und '.catch (function (error) {throw error;});' sind sinnlos - es funktioniert auch ohne sie - und sollte einfach weggelassen werden . Vor allem, wenn Sie lesbaren und wartbaren Code möchten. – Bergi

0

Wenn Sie nicht das Versprechen wollen gelöst zu bekommen, bevor das Login abgeschlossen ist, dann werden Sie entweder Ihre httplogin Funktion einen Rückruf machen nehmen und es wie folgt aus:

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

oder Rückkehr machen ein Versprechen, und es zum Beispiel wie folgt ausführen:

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

es gibt mehr Möglichkeiten, es mit dem Versprechen zu tun, aber das ist der einfachste Weg.

In beiden Fällen müssen Sie Ihre httplogin Funktion Signal ihre Beendigung, indem Sie entweder den Rückruf, dass es als ein Argument oder die Lösung der Versprechen, die es zurückgibt, aufrufen.

+0

Eigentlich war das das Problem kann ich Versprechen in Versprechen hinzufügen? Ich meine, wie kann ich meine http-Funktion einpacken? es wird wirklich nett von Ihnen sein, wenn Sie mir zeigen können, wie bkz ich versuchte und es für mich nicht funktionierte – Alex

1

Rewrite httplogin und httpafterlogin Versprechungen zurück:

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); 
    }); 
} 

dann .then verwenden wie rsp vorgeschlagen:

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; 
    }); 
} 

diese Weise wird der Block resolve(restautanttables) enthält, wird nicht aufgerufen, bis httplogin

vervollständigt
+0

Ja auf Ihrem ersten Satz, aber vermeiden Sie die ['Promise' Konstruktor antipattern] (http://stackoverflow.com/ q/23803743/1048572)! – Bergi

+0

ist das besser?Wenn nicht würde ich eine Erklärung schätzen, ich möchte lernen, aber die Suchergebnisse schienen meist überflüssiges Wrapping von Funktionen, die bereits Versprechen (statt Callback-Stil Funktionen in diesem Beispiel) – thedarklord47

+0

zurückgegeben, glaube ich, dass dies die gebrochene Fehler Verkettung (die Haupt behoben Negativ des Anti-Patterns zu meinem Verständnis) – thedarklord47