2016-11-21 5 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 ") 
}) 

проблема заключается в том, что она возвращает пустой массив. Но когда я попытался проверить и console.log в функции afterlogin, и я увидел, что массив действительно заполнен, но этот код работает после того, как обещание было разрешено. IN SHORT: как я могу связать решение в ресторане обещать не отправлять данные до тех пор, пока функция входа в систему не будет завершена?

другими словами, как я могу получить заполненный массив с информацией из afterlogin funtion?

+0

Я не вижу ничего плохого ... возможно, вы оставили код или что-то еще? если 'data' содержит ваш массив, то все хорошо. –

+0

'httpafterlogin' нуждается в том же обещании, что и в другом. –

+0

Но как Kevin B я пытался, но не работал – Alex

ответ

0

Используйте обещания на протяжении всего кода - вы можете упростить свой код, используя пакет 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 (функция (данные) {return data;})' и '.catch (функция (ошибка) {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? вам будет очень приятно, если вы сможете показать мне, как я пробовал bkz, и это не сработало для меня. – Alex

1

переписывает httplogin и httpafterlogin вернуть обещание:

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 как RSP предложил:

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

таким образом, блок, содержащий resolve(restautanttables) не дозвонился до httplogin не завершат

+0

Да в первом предложении, но избегайте ['promise' конструктора antipattern] (http://stackoverflow.com/ д/23803743/1048572)! – Bergi

+0

это лучше?если бы не я был бы признателен за объяснение, я бы хотел узнать, но результаты поиска, казалось, в основном включали избыточную упаковку функций, которые уже вернули обещания (а не функции стиля обратного вызова в этом примере). – thedarklord47

+0

Я считаю, что это исправляет разбитую цепочку ошибок (основная отрицательный анти-шаблон для моего понимания) – thedarklord47

Смежные вопросы