Javascript: 如何确保在使用数据之前fetch()已经完成?
Javascript: how to ensure that fetch() has finished before using the data?
我正在努力使用 fetch()
,我正在使用它来检索 JSON。我 认为 问题是代码在 fetch()
实际下载并处理之前完成并尝试 'act' 数组。我最初写了一个更简单的版本,导致了同样的问题;此处的大部分代码 is from Google Developers.
如下所示(仅包括 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()
}
看来您正在尝试使异步代码同步,这不是一个好主意。
只是 return 从 fetch 中获取数据的承诺,如下所示:
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
return 是一个可以解决或拒绝的承诺,因此任何调用者都可以等待这些事件。
请记住,我还没有对此进行测试。您需要始终使用承诺。正如您所发现的,尝试强制异步代码同步是不可靠的。
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
注意 requestJSONResult
的第 2 行:return fetch(....)
。我们 return 函数的承诺。
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);
});
我正在努力使用 fetch()
,我正在使用它来检索 JSON。我 认为 问题是代码在 fetch()
实际下载并处理之前完成并尝试 'act' 数组。我最初写了一个更简单的版本,导致了同样的问题;此处的大部分代码 is from Google Developers.
如下所示(仅包括 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()
}
看来您正在尝试使异步代码同步,这不是一个好主意。
只是 return 从 fetch 中获取数据的承诺,如下所示:
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
return 是一个可以解决或拒绝的承诺,因此任何调用者都可以等待这些事件。
请记住,我还没有对此进行测试。您需要始终使用承诺。正如您所发现的,尝试强制异步代码同步是不可靠的。
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
注意 requestJSONResult
的第 2 行:return fetch(....)
。我们 return 函数的承诺。
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);
});