我是Java的新手,但我仍然全神贯注于编写promise。

function addToList(data) {
    conversationList = data.Body.Conversations
    console.log(conversationList)
    for (i=0; i<conversationList.length; i++) {
        fullInbox.push(conversationList[i])
    }
    console.log(fullInbox.length)
}

var fullInbox = []
var maxLenReturn = 200
var offset = 0
function fetchData(offset){
    fetch(asynchCall)
    .then(response=>{return response.json()})
    .then(data=>{
        var fullLength = data.Body.TotalConversationsInView
        console.log(fullLength)
        addToList(data)
        if (offset < fullLength-maxLenReturn) {
            offset+= maxLenReturn
            fetchData(offset)
        }
    })
}

fetchData(offset)
// trying to make something like this work
.then( .... console.log(fullInbox.length))


我在fetchData函数中有一个循环,并希望将其包装在promise中,以便完成后可以打印出fullInbox

var promise1 = new Promise(function(resolve, reject) {
  var fullInbox = []
  var maxLenReturn = 200
  var offset = 0
  fetchData(offset);
  resolve(fullInbox)
});

promise1.then(function(value) {
  console.log('promise resolved')
  console.log(value);
});


我想我需要在resolve内的fetchData,但是不确定如何编写它,以便它在解决之前遍历所有内容。

最佳答案

从您的代码中可以看到,您的addToList函数是同步的,因此它不需要做任何承诺。但是,下次调用fetchData时,您需要处理承诺。因此,这样的事情会起作用:

function fetchData(offset){
    return fetch(asynchCall)
    .then(response=>{return response.json()})
    .then(data=>{
        var fullLength = data.Body.TotalConversationsInView
        console.log(fullLength)
        addToList(data)
        let promise;
        if (offset < fullLength-maxLenReturn) {
            offset+= maxLenReturn
            promise = fetchData(offset)
        } else {
            promise = Promise.resolve();
        }
        return promise;
    })
}


而且,如果您想使用async/await style syntax,则阅读起来会更好:

async function fetchData(offset){
    let response = await fetch(asynchCall)
    let data = await response.json();
    let fullLength = data.Body.TotalConversationsInView
    console.log(fullLength)
    addToList(data)
    if (offset < fullLength-maxLenReturn) {
      offset+= maxLenReturn
      await fetchData(offset)
    }
}


当前所有主要浏览器都支持Async / await,并且您可以对较旧的浏览器进行polyfill。由于其语法更简洁,我强烈建议您使用它。这将使您免于编写错误。



因此,这是一个简短的版本,可以执行您需要的操作。它使用异步/等待。每次对fetchData的调用都会从其一直传递到末尾的偏移量返回收件箱项目。使用默认参数可以避免使用全局变量。

async function fetchData(offset = 0, maxLenReturn = 200) {
    let response = await fetch(asyncCall)
    let data = await response.json();
    let inbox = data.Body.Conversations;
    let fullLength = data.Body.TotalConversationsInView
    if (offset < fullLength-maxLenReturn) {
      offset+= maxLenReturn
      inbox.push(...await fetchData(offset))
    }
    return inbox;
}

let fullInbox = fetchData()

09-25 17:09