使用 foreach 循环创建数组并使用 webworker postMessage 传回
Create array using foreach loop and pass it back with webworker postMessage
我有这个网络工作者代码:
onmessage = (e) => {
console.log(e);
fetch('https://example.com/wp-json/wp/v2/posts?per_page=20')
.then( (res) => res.json() )
.then( async (data) => {
let imagesData = [];
data.forEach( (item) => {
fetch(item._links["wp:featuredmedia"][0].href)
.then( (res) => res.json() )
.then( (img) => {
imagesData.push({
title: item.title.rendered,
link: item.link,
src: img.source_url
});
});
});
await postMessage([imagesData]);
});
} //end onmessage
我正在尝试在获取所有资源后创建一个数组,但我无法实现。目前 imagesData
数组将为空,如果将其移动到推送数组数据的 .then()
中,我将收到多条消息,每个数组包含一个条目。我如何解决这个问题,让一个数组包含所有获取的信息以传回创建工作程序的位置?
注意:该代码在我的主脚本中运行良好,我只是将其移交给网络工作者!问题不在于 fetch 提供的数据及其结构,而在于 imagesData
数组,这是我想要填充并发送回主脚本的数组。
Array#forEach
同步执行,所以当你到达 postMessage
时,数组仍然是空的。
相反,您需要的是 Promise.all
。
Promise.all
将一组 promise 转换为单个 promise,该 promise 解析为一组已解析的值。内部承诺是并行执行的,因此解决时间应该大致与 longest-running 内部承诺的时间一样长。
方便地,将 async
函数作为回调传递给 Array#map
将原始数组转换为承诺数组。一种常见的用法是使用 fetch
请求映射 URL 字符串或参数数组,将结果包装在 Promise.all
:
中
const usernames = await Promise.all(
['123', '456', '789'].map(async id => {
const res = await fetch(`/api/users/${id}`)
const { username } = await res.json()
return username
})
)
在你的情况下,你需要替换这个:
let imagesData = [];
data.forEach( (item) => {
fetch(item._links["wp:featuredmedia"][0].href)
.then( (res) => res.json() )
.then( (img) => {
imagesData.push({
title: item.title.rendered,
link: item.link,
src: img.source_url
});
});
});
await postMessage([imagesData]);
有了这个:
const imagesData = await Promise.all(
data.map(async item => {
const res = await fetch(item._links["wp:featuredmedia"][0].href)
const img = await res.json()
return {
title: item.title.rendered,
link: item.link,
src: img.source_url
}
})
)
另外,worker的postMessage
是同步的,没必要await
。您也不需要在发布之前将 imagesData
包装在外部数组中:
postMessage(imagesData);
我有这个网络工作者代码:
onmessage = (e) => {
console.log(e);
fetch('https://example.com/wp-json/wp/v2/posts?per_page=20')
.then( (res) => res.json() )
.then( async (data) => {
let imagesData = [];
data.forEach( (item) => {
fetch(item._links["wp:featuredmedia"][0].href)
.then( (res) => res.json() )
.then( (img) => {
imagesData.push({
title: item.title.rendered,
link: item.link,
src: img.source_url
});
});
});
await postMessage([imagesData]);
});
} //end onmessage
我正在尝试在获取所有资源后创建一个数组,但我无法实现。目前 imagesData
数组将为空,如果将其移动到推送数组数据的 .then()
中,我将收到多条消息,每个数组包含一个条目。我如何解决这个问题,让一个数组包含所有获取的信息以传回创建工作程序的位置?
注意:该代码在我的主脚本中运行良好,我只是将其移交给网络工作者!问题不在于 fetch 提供的数据及其结构,而在于 imagesData
数组,这是我想要填充并发送回主脚本的数组。
Array#forEach
同步执行,所以当你到达 postMessage
时,数组仍然是空的。
相反,您需要的是 Promise.all
。
Promise.all
将一组 promise 转换为单个 promise,该 promise 解析为一组已解析的值。内部承诺是并行执行的,因此解决时间应该大致与 longest-running 内部承诺的时间一样长。
方便地,将 async
函数作为回调传递给 Array#map
将原始数组转换为承诺数组。一种常见的用法是使用 fetch
请求映射 URL 字符串或参数数组,将结果包装在 Promise.all
:
const usernames = await Promise.all(
['123', '456', '789'].map(async id => {
const res = await fetch(`/api/users/${id}`)
const { username } = await res.json()
return username
})
)
在你的情况下,你需要替换这个:
let imagesData = [];
data.forEach( (item) => {
fetch(item._links["wp:featuredmedia"][0].href)
.then( (res) => res.json() )
.then( (img) => {
imagesData.push({
title: item.title.rendered,
link: item.link,
src: img.source_url
});
});
});
await postMessage([imagesData]);
有了这个:
const imagesData = await Promise.all(
data.map(async item => {
const res = await fetch(item._links["wp:featuredmedia"][0].href)
const img = await res.json()
return {
title: item.title.rendered,
link: item.link,
src: img.source_url
}
})
)
另外,worker的postMessage
是同步的,没必要await
。您也不需要在发布之前将 imagesData
包装在外部数组中:
postMessage(imagesData);