我试图在JS中将多个异步请求链接在一起。基本上,我想从LastFM API中检索艺术家信息,然后使用该信息查找他们的顶级曲目。
到目前为止,我可以成功获取艺术家信息,让它返回,并在下一步打印出信息。但是,一旦我尝试对顶部曲目进行第二次请求,就不会打印正文,它会立即进入下一步。
我已经尝试了很多这种代码的不同组合以及不同类型的请求,但我没有运气。我只想成功地做一个请求1,如果成功,那么按照正确的顺序跟进其他人。
var artistInfo = {
method: 'GET',
url: 'http://localhost:3000/users/db/artistInfo/' + artistName
};
var topTracks = { method: 'GET',
url: 'http://localhost:3000/users/db/topTracks/' + artistName
};
/* Dependencies */
var Promise = require('bluebird');
var reqP = Promise.promisifyAll(require('request-promise'));
reqP(artistInfo)
.then(function(info) {
console.log("got here 1");
return info;
})
.then(function(artist) {
console.log(artist);
reqP(topTracks)
.then(function(body) {
console.log(body);
console.log("got here 2");
return body;
});
return 'test';
})
.then(function(content) {
console.log(content);
return 'test2';
})
.catch(function(err) {
throw err;
});
答案 0 :(得分:1)
要对这两个请求进行排序并使外部public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->virtualFields['name'] = sprintf('CONCAT(%s.first_name, " ",%s.last_name)', $this->alias, $this->alias);
$this->virtualFields['namewithemail'] = sprintf('CONCAT(%s.first_name, " ", %s.last_name, " (", %s.email, ")")', $this->alias, $this->alias, $this->alias);
$this->displayField = "namewithemail";
}
等待两者,您需要返回内部承诺(.then()
处理程序内部的承诺)以链接它们。如果你没有归还它们,那么没有任何东西被链接到父承诺,因此父承诺不会等待子承诺。请参阅我将.then()
添加到return
的行:
return reqP(topTracks)
仅供参考,看起来你的两个请求并不相互依赖,所以你也可以并行:
var artistInfo = {
method: 'GET',
url: 'http://localhost:3000/users/db/artistInfo/' + artistName
};
var topTracks = { method: 'GET',
url: 'http://localhost:3000/users/db/topTracks/' + artistName
};
/* Dependencies */
var Promise = require('bluebird');
var reqP = Promise.promisifyAll(require('request-promise'));
reqP(artistInfo)
.then(function(info) {
console.log("got here 1");
return info;
})
.then(function(artist) {
console.log(artist);
// *** add return here ***
return reqP(topTracks)
.then(function(body) {
console.log(body);
console.log("got here 2");
return body;
});
})
.then(function(content) {
console.log(content);
return 'test2';
})
.catch(function(err) {
throw err;
});
答案 1 :(得分:0)
首先,我不知道为什么要宣传基于承诺的图书馆。有几种方法可以做到这一点,但我会给你我认为最干净的方式,但它需要bluebird(无论如何你在你的例子中使用,所以不应该是一个问题)
您的第二个请求看起来不像您的第一个请求,您可以使用Promise.props()
/* Dependencies */
var Promise = require('bluebird');
var request = require('request-promise');
var artistInfo = request({
method: 'GET',
url: 'http://localhost:3000/users/db/artistInfo/' + artistName
});
var topTracks = request({
method: 'GET',
url: 'http://localhost:3000/users/db/topTracks/' + artistName
});
Promise.props({
artistInfo: artistInfo,
topTracks: topTracks
}).then(function(result) {
console.log(JSON.stringify(result.artistInfo,null,2));
console.log(JSON.stringify(result.topTracks,null,2));
})
.catch(function(err) {
console.error(err);
});
那么这里发生了什么? Promise.props
允许您传递属性为promises的对象。然后这些承诺将并行执行,并且在两者都被解决之前不会解决承诺(或者如果两者都失败,它将会丢失)。
至于链接承诺,你需要确保返回一个承诺。这是允许你避免丑陋嵌套的原因
/* Dependencies */
var Promise = require('bluebird');
var request = require('request-promise');
request({
method: 'GET',
url: 'http://localhost:3000/users/db/artistInfo/' + artistName
})
.then(function(artistInfo) {
console.log(artistInfo);
return request({
method: 'GET',
url: 'http://localhost:3000/users/db/topTracks/' + artistName
});
})
.then(function(topTracks) {
console.log(topTracks);
})
.catch(function(err) {
console.error(err);
});