我正在尝试使用Slack的API学习基于光标的分页。我的目标是使用channel.history方法返回所有消息的数组。
我有一个javascript递归获取函数,但我似乎无法让局部变量“final”正确返回。
记录“分页结果成功”的部分是按预期记录并返回数组,长度为204.
当在该范围之外调用“final”时,长度为0。
我已经尝试过在哪里返回变量final,但似乎无法使其正常工作。我认为这与不使用回调函数有关,但我不知道在哪里实现它。
这就是我所拥有的(删除了我的Slack令牌)。
function paginate() {
let final = [];
let selectChannel = function(ts) {
fetch('https://slack.com/api/channels.history?token=MY_TOKEN&channel=C6W9FH2S0&latest=' + ts)
.then(response => response.json())
.then(responseData => {
let messages = responseData.messages;
if (!responseData.has_more) {
final.push.apply(final, messages);
console.log('Pagination results successfull, 204 items in the array!', final);
return final;
} else {
final.push.apply(final, messages);
selectChannel(messages[messages.length - 1].ts);
}
return final;
})
.catch(error => {
console.log('Error fetching and parsing data', error);
});
}
selectChannel(new Date());
// Returning as 0, when I am expecting 204
console.log("Final Output", final.length);
return final;
}
var x = paginate();
// By extention, this is returning as 0, when I am expecting 204 as well
console.log("Output", x.length);
答案 0 :(得分:1)
这是因为then函数内的代码稍后执行(hello async await:)。
fetch()
返回将来执行某个点的承诺,并且可以返回此承诺并添加另一个then()方法并在其中调用console.log()
以下是按执行顺序排列的代码块,这可能会澄清:
function paginate() { /* 2 */
let final = [];
let selectChannel = function(ts) { /* 4 */
fetch('https://slack.com/api/channels.history?token=MY_TOKEN&channel=C6W9FH2S0&latest=' + ts)
.then(response => response.json() /* 8 */)
.then(responseData => { /* 9 */
let messages = responseData.messages;
if (!responseData.has_more) {
final.push.apply(final, messages);
console.log('Pagination results successfull, 204 items in the array!', final);
return final;
} else {
final.push.apply(final, messages);
selectChannel(messages[messages.length - 1].ts);
}
return final;
})
.catch(error => { /* 10 */
console.log('Error fetching and parsing data', error);
});
}
selectChannel(new Date()); /* 3 */
// Returning as 0, when I am expecting 204
console.log("Final Output", final.length); /* 5 */
return final; /* 6 */
}
var x = paginate(); /* 1 */
// By extention, this is returning as 0, when I am expecting 204 as well
console.log("Output", x.length); /* 7 */
正如您所看到的那样,步骤7记录了x.length结果,而仅在步骤9中,此结果最终填充(最终变量在步骤/代码块9中填充)
在异步世界中,您的代码将(必须)看起来像这样:
async function selectChannel() {
try {
var response = await fetch('https://slack.com/api/channels.history?token=MY_TOKEN&channel=C6W9FH2S0&latest=' + ts);
var responseData = await response.json();
let messages = responseData.messages;
if (!responseData.has_more) {
final.push.apply(final, messages);
console.log('Pagination results successfull, 204 items in the array!', final);
return final;
} else {
final.push.apply(final, messages);
await selectChannel(messages[messages.length - 1].ts);
}
return final;
} catch (error) {
console.log('Error fetching and parsing data', error);
}
}
async function execute() {
var finalData = await selectChannel(new Date());
console.log("Final Output", finalData.length);
}
execute() // optionally: .then(x=> console.log('we are finished executing!'));