过去几天我一直试图了解服务器端的承诺,但我还没有找到任何可行的方法。 Bluebird但似乎是一个不错的选择。在API之后,我试图对其进行测试,但我收到错误:"无法调用方法'然后'未定义"。我查找了similar错误,但我无法使我的工作类似。
到目前为止,这是我对蓝鸟的尝试:
var Promise = require('bluebird')
var cheerio = require('cheerio');
var request = require('request');
// do I need this?
// var request = Promise.promisify(require('request'));
// Promise.promisifyAll(request);
function getA() {
$(path).each(function(i,e){
link = $(this).attr("href");
getB(...).then(function(urls) {
console.log('type of urls: ' + typeof(urls) + urls);
// getC();
}).then(function(urls) {
// getD();
});
});
}
function getB() {
return new Promise(function(fullfill, reject) {
request(selectedShow, function (err, resp, page) {
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(page);
$(path).each(function(i,e){
stuff.push($(this).text());
}
}); // end each loop
} // end error and status check
fullfill(stuff);
}); // end request
}
function getC() {
// use 'stuff' array to make requests and fill another array
}
function getD() {
// use the arrays to build an object
}
答案 0 :(得分:0)
首先要注意的是,您应该在函数getB
中返回promise。
其次,你太早实现了这个承诺。相反,您应该在收到您的请求回复后履行/拒绝:
function getB() {
return new Promise(function(fullfill, reject) {
request(selectedShow, function(err, resp, page) {
// at this point you have a response could be error/success
if (!err && resp.statusCode == 200) {
var $ = cheerio.load(page);
$(path).each(function(i, e) {
stuff.push($(this).text());
});
// fulfill here, since success
fullfill(stuff);
} else {
reject("error"); // usually reject on error
}
});
// TOO EARLY, COS YOU DON'T HAVE A RESPONSE YET!
// fullfill(stuff);
}); // end request
}
我不希望这个答案绝对解决你的问题,但它应该有所帮助。在应用上述更改后,请随时询问其他方向。
在对此答案的评论中回答OP的问题
您必须将getA
的实施修改为以下效果:
function getA() {
$(path).each(function(i,e){
link = $(this).attr("href");
getB(...).then(function(urls) {
// NOTE: the `urls` parameter will have same value as the
// `stuff` used in calling `fulfill(stuff)`
console.log('type of urls: ' + typeof(urls) + urls);
// getC();
// you may also call getD() here
}).then(function(urls) {
// this additional `.then()` chain is not necessary as you could
// have done what it is you wanted to do here inside the first `then(...)`
// getD();
});
});
}
现在关于执行的顺序;将所有内容放在一起 - 您的原始代码段并在此答案中应用我对其所做的更改...
当您致电getA()
时,会拨打getB()
并在getB()
成功执行之后 然后 {{1} }和getC()
将分别执行 。总之,订单是getD()
- > getA()
- 如果getB()执行成功结果 - > getB()
- > getC()
。
现在让我们定义另外两个函数getC()
和getWhatever
:
ohNo
我们稍后会修改function getWhatever(){
console.log("whateeveeer!");
}
function ohNo(){
console.log("eeeeew!");
}
:
getA
对function getA() {
$(path).each(function(i,e){
link = $(this).attr("href");
getB(...).then(function(urls) {
console.log('type of urls: ' + typeof(urls) + urls);
getC();
}).then(function(urls) {
getD();
}).catch(function(){
// you only reach this point if the outcome of getB was an error
ohNo();
});
getWhatever();
});
}
进行了这一新的更改,以下是不同结果的执行顺序:
当getA
的结果成功时:
getB
- > getA()
- > getB()
- > getWhatever()
- > getC()
当getD()
的结果成功时:
getB
- > getA()
- > getB()
- > getWhatever()
我希望你的所有问题现在得到充分解决。