我怀疑这是异步问题,
我无法理解问题所在。
所以我做了多个api请求并用响应填充列表。
然后我有一个绘制数据的D3.js脚本,
虽然收到undefined,但我在这里用一个简单的日志替换它。
(当然控制台稍后会实时“评估”这些值,但是记录一个节点[0]项确实是未定义的。)
我测试了为后续脚本设置超时但无效,
自从请求以来我无法提出回调解决方案
本身就是一个回调。
(我知道forEach
是在这里使用的正确方法,但我也试图通过立即返回来实现赋值功能,这也是我无法实现的功能。
variables=["pageid1","pageid2","pageid3"];
nodes=[];
variables.map(function(variable){
FB.api("/"+variable,"GET",{fields:'name,picture.type(large),engagement'},function(response){
if(!response.error){
nodes.push(response);
}
});
});
console.log(nodes);
答案 0 :(得分:3)
您可以将请求包装在承诺中。然后等待所有承诺得到解决,在这种情况下,您的节点变量将填充响应。 你可以这样做:
nodes=[];
function sendRequest( variable ) {
return new Promise ( ( resolve, reject ) => {
FB.api("/"+variable,"GET",{fields:'name,picture.type(large),engagement'},function(response){
if(!response.error)
resolve( response );
});
});
}
Promise.all( variables.map(function( variable ) {
return sendRequest( variable );
})).then( values => {
/* All the responses are solved here */
nodes = values.splice( 0 );
console.log( nodes );
});
答案 1 :(得分:1)
我怀疑它是异步性的问题
是的,当然,您的console.log可以在.api
完成之前触发。试图用setTimeout
延迟它只是糟糕的编程(它是一个猜谜游戏)。
nodes
上的任何处理都需要在.api
回调中。如果您要处理多个异步调用并且需要在处理nodes
之前完成所有操作,那么您应该使用d3.queue之类的内容。来自docs(bolding mine):
队列使用可配置的并发性评估零个或多个延迟异步任务:您可以控制同时运行的任务数。 当所有任务完成或发生错误时,队列会将结果传递给您的等待回调。这个库类似于Async.js的并行(当并发是无限的时候),系列(当并发是1时)和队列,但是占用的空间要小得多:从版本2开始,d3-queue约为700字节gzip,相比之下4,300 for Async。
在您的情况下,代码可能如下所示(未经测试):
var q = d3.queue();
variables.forEach(function(d) {
q.defer(FB.api, "/" + variable, , "GET", {fields: 'name,picture.type(large),engagement' });
});
q.await(function(error, response1, response2, response3) {
if (error) throw error;
// build out nodes from responses...
});
答案 2 :(得分:1)
使用async / await的不同方法和一些修复(let,arrow functions,...):
let variables = ['pageid1', 'pageid2', 'pageid3'];
cosnt sendRequest = (variable) => {
return new Promise ((resolve, reject) => {
FB.api('/' + variable, {fields:'name,picture.type(large),engagement'}, (response) => {
if(!response.error) {
resolve(response);
} else {
reject(response.error);
}
});
});
};
const getData = async () => {
let nodes = [];
for (let i = 0; i < variables.length; i++) {
let response = await sendRequest(variables[i]);
nodes.push(response);
}
console.log(nodes);
};
getData();