2017-09-24 103 views
1

我试图学习与Slack的API基于光标的分页。我的目标是使用channel.history方法返回所有消息的数组。从递归获取请求数组不正确返回

我有一个javascript递归获取函数,但我似乎无法得到本地变量“最终”,以正确返回。

其中它记录“分页结果成功的”正在记录和返回数组作为具有204

当“最终”在该范围之外的被调用时,长度为0

长度预期的部分

我试过试验我在哪里返回变量final,但似乎无法得到它的工作。我认为这与不使用回调函数有关,但我不确定在哪里实现。

这是我的(我的松弛令牌删除)。

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); 
+2

fetch is async ... – Hitmands

+1

'final'对于一个变量来说是一个非常非常糟糕的名字。 – timmyRS

+0

不够公平,它是一个实验项目,所以我没有把时间放在变量命名上。产出很可能是一个更好的主意。我认为那是解决异步方面的问题。也为快速回复ty。 – DJBrandoK

回答

1

这是因为then函数内的代码稍后执行(hello async await :)。

fetch()返回在未来执行的一些点,并可以返回这一承诺的承诺,并添加另一个则()方法,并在那里的console.log()

这里是你的代码块的执行顺序,正如你可以看到步骤7将记录x.length结果而,仅在步骤9该结果finaly填充(最终变量被填充在步骤/码块9)

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 */ 

:这可能澄清事

在异步窝您的代码将(必须)看起来像这样:

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!')); 
+0

谢谢你的详细回复和解释(仍然我必须为selectChannel添加一个“ts”参数,并让execute函数返回finalData以使它返回selectChannel之外的某个人,如果我希望它返回204,它现在返回100。你已经回答了我的问题,但是现在我需要找出为什么它只接受第一次访问的数据,而不是递归地执行。非常感谢你! – DJBrandoK

+0

我调整了你提供的代码并使用这个https获得了我的目标://jsfiddle.net/gp6f8Lyv/ – DJBrandoK