2017-08-15 49 views
1

我正在努力与fetch(),我用它来检索JSON。我认为问题是代码完成并试图在fetch()实际下载并处理它之前在阵列上“动作”。我最初写了一个更简单的版本,导致了同样的问题。这里的大部分代码是is from Google DevelopersJavascript:如何在使用数据之前确保fetch()已完成?

如下图所示(setTimeout的只包括来演示该问题)访问同一阵列两次当我得到不同的结果,第二分开:

dataResultArray = requestJSONResult(searchString); 

console.log(dataResultArray);   // logs '[]' 
console.log(dataResultArray.length); // logs '0' 

setTimeout(function(){ 
    console.log(dataResultArray);   // logs the actual JSON array contents 
    console.log(dataResultArray.length); // logs the real array length 
}, 1000); 


function requestJSONResult(searchString) { 
    var tempArray = [] 

    fetch(`/search/?term=${searchString}`) 
    .then(status) 
    .then(json) 
    .then(function(data) { 
     tempArray.push(...data) 
    }).catch(function(error) { 
    console.log('Request failed', error); 
    }); 

    return tempArray; 
} 

function status(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return Promise.resolve(response) 
    } else { 
    return Promise.reject(new Error(response.statusText)) 
    } 
} 

function json(response) { 
    return response.json() 
} 
+0

google javascript promise and/or callbacks – yBrodsky

+0

您需要正确使用promise。从你的函数中返回承诺并附加一个'then'处理程序,而不是试图将结果推送到一个数组中。没有办法可以可靠地工作。 – Amy

+0

一旦使用了promise,就会使用'then'回调,即使在调用这些函数的主脚本中也是如此。您只能访问那里的异步检索数据。 – trincot

回答

2

您似乎在试图让你的异步代码同步哪些不是一个好主意。

刚刚回归的承诺,从获取到检索像这样的数据:

function requestJSONResult(searchString) { 
    return fetch(`/search/?term=${searchString}`) 
    .then(status) 
    .then(json); 
} 

function status(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return Promise.resolve(response) 
    } else { 
    return Promise.reject(new Error(response.statusText)) 
    } 
} 

function json(response) { 
    return response.json() 
} 


requestJSONResult(searchString) 
    .then(function(data) { 
    console.log(data); 
    console.log(data.length); 
    }) 
    .catch(function(error) { 
    console.log('Request failed', error); 
    }); 

现在你requestJSONResult返回一个承诺,既可以解决或拒绝,所以任何调用者可以等待这些事件。

1

请记住,我没有测试过这个。你需要始终使用promise。正如你发现的,试图强制异步代码同步是不可靠的。

function status(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return Promise.resolve(response) 
    } else { 
    return Promise.reject(new Error(response.statusText)) 
    } 
} 

通知行2的requestJSONResultreturn fetch(....)。我们从函数返回承诺。

function requestJSONResult(searchString) { 
    return fetch(`/search/?term=${searchString}`) 
     .then(status) 
     .then(function(response) { 
      return response.json(); 
     }) 
     .catch(function(error) { 
      console.log('Request failed', error); 
     }); 
} 

requestJSONResult(searchString) 
    .then(function(result) { 
     console.log(result); 
    }); 
相关问题