承诺迭代一个链接数组,使用 mercury-client 解析它们并将解析的内容推送到一个新数组中
Promise to iterate over an array of links, parsing them using mercury-client and pushing the parsed content into a new array
我有一个链接数组,我想使用 mercury-client
解析其内容,并将结果推入 articles
数组。
* parseLinks() {
const links = yield this.getInboxMessages() // It will be ['link1', 'link2', ..., 'linkN']
const articles = []
return new Promise((resolve, reject) => {
for (let link of links) {
mercury.parse(link).then((data) => {
articles.push(data)
})
}
resolve(articles)
})
}
我看不出有什么问题,因为我只得到 []
。我试图将 Promise
移动到 for..of
内,但结果保持不变。
通过删除循环并使其仅解析 links
数组的第一个索引,我没有遇到任何问题。
你得到 []
篇文章是因为你调用 resolve(articles)
sync'ly 而你的 for
循环将数据异步推送到那里。与其将已解决的 data
推入您的文章,不如将 mercury.parse(link)
承诺推入一个数组。您最终会得到一系列待解决的 mercury-client promises。然后,您可以在该数组上使用 Promise.all 并仅在所有依赖的承诺都已解决时才解决 articles
。
你在 articles
被填满之前解决得太早了。
您可以将整个 return
块替换为:
return Promise.all(links.map(link => mercury.parse(link)));
这将 return 只有在每 link 被处理一次后,一个已解决的承诺。
如果(且仅当)mercury.parse
函数可以处理作为裸函数引用传递而无需将 mercury
作为 this
上下文变量传递,您可以简化进一步:
return Promise.all(links.map(mercury.parse));
您可以通过 Array.prototype.reduce
和 Promise.all
组合来实现。如下所示。
function parseLinks () {
const links = [....]
return Promise.all(links.reduce((promises, link) => {
return promises.concat(mercury.parse(link))
}, []))
}
parseLinks().then(links => console.log(links))
我有一个链接数组,我想使用 mercury-client
解析其内容,并将结果推入 articles
数组。
* parseLinks() {
const links = yield this.getInboxMessages() // It will be ['link1', 'link2', ..., 'linkN']
const articles = []
return new Promise((resolve, reject) => {
for (let link of links) {
mercury.parse(link).then((data) => {
articles.push(data)
})
}
resolve(articles)
})
}
我看不出有什么问题,因为我只得到 []
。我试图将 Promise
移动到 for..of
内,但结果保持不变。
通过删除循环并使其仅解析 links
数组的第一个索引,我没有遇到任何问题。
你得到 []
篇文章是因为你调用 resolve(articles)
sync'ly 而你的 for
循环将数据异步推送到那里。与其将已解决的 data
推入您的文章,不如将 mercury.parse(link)
承诺推入一个数组。您最终会得到一系列待解决的 mercury-client promises。然后,您可以在该数组上使用 Promise.all 并仅在所有依赖的承诺都已解决时才解决 articles
。
你在 articles
被填满之前解决得太早了。
您可以将整个 return
块替换为:
return Promise.all(links.map(link => mercury.parse(link)));
这将 return 只有在每 link 被处理一次后,一个已解决的承诺。
如果(且仅当)mercury.parse
函数可以处理作为裸函数引用传递而无需将 mercury
作为 this
上下文变量传递,您可以简化进一步:
return Promise.all(links.map(mercury.parse));
您可以通过 Array.prototype.reduce
和 Promise.all
组合来实现。如下所示。
function parseLinks () {
const links = [....]
return Promise.all(links.reduce((promises, link) => {
return promises.concat(mercury.parse(link))
}, []))
}
parseLinks().then(links => console.log(links))