在获取请求后执行语句
Executing a statement after a fetch request
我的代码结构如下:
var cdict = new Map();
fetch("randomurl")
.then(res => res.json())
.then(data => {
for (const obj of data.result) {
// insert stuff into Map cdict
}
counter(0).then(res => {
console.log(cdict);
})
// ^ here after calling of counter i need to do stuff
});
const cbegin = 0;
const ccount = 10;
function counter(cnt) {
if (cnt < ccount) {
setTimeout( () => {
cnt++;
fetch(someurl)
.then(res => res.json())
.then(data => {
for (const obj of data.result) {
// do stuff
}
})
.catch(err => {
console.log(err);
});
counter(cnt);
}, 1000);
}
}
在执行 counter(0)
调用及其所有提取请求后,我希望执行一行 console.log(cdict);
如何实现?这是调用延迟 1 秒的提取请求的正确方法吗?
不要将 setTimeout
事件队列回调与基于承诺的代码混合 -
const sleep = time =>
new Promise(resolve => setTimeout(resolve, time))
async function main()
{ console.log("please wait 5 seconds...")
await sleep(5000)
console.log("thanks for waiting")
return "done"
}
main().then(console.log, console.error)
不要每次需要 JSON 时都写 .then(res => res.json())
。写一次,重复使用-
const fetchJSON(url, options = {}) =>
fetch(url, options).then(res => res.json())
async function main()
{ const data = await fetchJSON("path/to/data.json")
console.log("data received", data)
return ...
}
main().then(console.log, console.error)
不要尝试在 Promises 之外声明变量并在以后修改它们。你不能return the result of an asynchronous call。异步数据需要包含在承诺中,否则您将在代码中寻找难以发现的错误 -
async function main(urls)
{ const result = []
for (const u of urls) // for each url,
{ result.push(await getJSON(u)) // await fetch and append to result
sleep(1000) // wait 1 second
}
return result
}
const myUrls =
[ "foo/path/data.json"
, "another/something.json"
, "and/more/here.json"
]
main(urls)
.then(result => /* counter logic */)
.then(console.log, console.error)
继续抽象你认为合适的 -
// give reusable functions a name; use parameters for configurable behaviour
async function fetchAll(urls, delay = 100)
{ const result = []
for (const u of urls)
{ result.push(await getJSON(u))
sleep(delay)
}
return result
}
async function counter(urls)
{ const results = await fetchAll(urls) // use our generic fetchAll
const cdict = /* counter logic... */
return cdict
}
const myUrls =
[ "foo/path/data.json"
, "another/something.json"
, "and/more/here.json"
]
counter(urls).then(console.log, console.error)
如您所见,async
和 await
防止使用 setTimeout
或 .then
回调时发生的嵌套。如果正确使用它们,您的代码将保持平坦,并且您可以以同步方式考虑您的代码。
我的代码结构如下:
var cdict = new Map();
fetch("randomurl")
.then(res => res.json())
.then(data => {
for (const obj of data.result) {
// insert stuff into Map cdict
}
counter(0).then(res => {
console.log(cdict);
})
// ^ here after calling of counter i need to do stuff
});
const cbegin = 0;
const ccount = 10;
function counter(cnt) {
if (cnt < ccount) {
setTimeout( () => {
cnt++;
fetch(someurl)
.then(res => res.json())
.then(data => {
for (const obj of data.result) {
// do stuff
}
})
.catch(err => {
console.log(err);
});
counter(cnt);
}, 1000);
}
}
在执行 counter(0)
调用及其所有提取请求后,我希望执行一行 console.log(cdict);
如何实现?这是调用延迟 1 秒的提取请求的正确方法吗?
不要将 setTimeout
事件队列回调与基于承诺的代码混合 -
const sleep = time =>
new Promise(resolve => setTimeout(resolve, time))
async function main()
{ console.log("please wait 5 seconds...")
await sleep(5000)
console.log("thanks for waiting")
return "done"
}
main().then(console.log, console.error)
不要每次需要 JSON 时都写 .then(res => res.json())
。写一次,重复使用-
const fetchJSON(url, options = {}) =>
fetch(url, options).then(res => res.json())
async function main()
{ const data = await fetchJSON("path/to/data.json")
console.log("data received", data)
return ...
}
main().then(console.log, console.error)
不要尝试在 Promises 之外声明变量并在以后修改它们。你不能return the result of an asynchronous call。异步数据需要包含在承诺中,否则您将在代码中寻找难以发现的错误 -
async function main(urls)
{ const result = []
for (const u of urls) // for each url,
{ result.push(await getJSON(u)) // await fetch and append to result
sleep(1000) // wait 1 second
}
return result
}
const myUrls =
[ "foo/path/data.json"
, "another/something.json"
, "and/more/here.json"
]
main(urls)
.then(result => /* counter logic */)
.then(console.log, console.error)
继续抽象你认为合适的 -
// give reusable functions a name; use parameters for configurable behaviour
async function fetchAll(urls, delay = 100)
{ const result = []
for (const u of urls)
{ result.push(await getJSON(u))
sleep(delay)
}
return result
}
async function counter(urls)
{ const results = await fetchAll(urls) // use our generic fetchAll
const cdict = /* counter logic... */
return cdict
}
const myUrls =
[ "foo/path/data.json"
, "another/something.json"
, "and/more/here.json"
]
counter(urls).then(console.log, console.error)
如您所见,async
和 await
防止使用 setTimeout
或 .then
回调时发生的嵌套。如果正确使用它们,您的代码将保持平坦,并且您可以以同步方式考虑您的代码。