2 回答

TA貢獻(xiàn)1825條經(jīng)驗(yàn) 獲得超4個(gè)贊
這里似乎同時(shí)存在幾個(gè)問題/誤解。讓我們?cè)囍淮慰匆淮巍?/p>
首先,您似乎認(rèn)為外部函數(shù)將返回(“傳遞”)您的回調(diào)的返回值
正如您在庫源代碼中看到的那樣,情況并非如此。
此外,它甚至沒有意義,因?yàn)榛卣{(diào)為每個(gè)項(xiàng)目調(diào)用一次。那么,對(duì)于 10 個(gè)項(xiàng)目,它將被調(diào)用 10 次,那么如何parseFileItems知道回調(diào)的 10 個(gè)返回值中的哪一個(gè)傳遞給外部?
從回調(diào)函數(shù)返回什么并不重要,因?yàn)樵損arseFileItems函數(shù)只是忽略它。此外,parseFileItems函數(shù)本身也不返回任何內(nèi)容。因此,結(jié)果new pdfreader.parseFileItems(...)將始終評(píng)估為undefined(并且undefined顯然沒有屬性then)。
其次,您似乎認(rèn)為這.then是函數(shù)調(diào)用的某種通用鏈接方法。
事實(shí)上,.then它是一種鏈接承諾的方式,或者對(duì)承諾的履行作出反應(yīng)。在這種情況下,任何地方都沒有任何承諾,特別parseFileItems是不返回承諾(它返回undefined如上所述),所以你不能調(diào)用.then它的結(jié)果。
根據(jù)文檔,您應(yīng)該自己對(duì)錯(cuò)誤和流結(jié)束做出反應(yīng)。因此,您的代碼將像這樣工作:
let pages = [];
new pdfreader.PdfReader()
.parseFileItems(pp, function(err, item) {
{
if (!item) {
// ****** Here we are done! ******
console.log("done" + pages.length) // The code that was in the `then` goes here instead
} else if (item.page) {
pages.push(lines);
rows = {};
} else if (item && item.text) {
// accumulate text items into rows object, per line
(rows[item.y] = rows[item.y] || []).push(item.text);
}
}
})
但是,我同意擁有一個(gè) promise 包裝器會(huì)更好,這樣您就不必將以下所有代碼填充到回調(diào)的if (!item)分支中。你可以這樣實(shí)現(xiàn),使用new Promise:
const promisifiedParseFileItems = (pp, itemHandler) => new Promise((resolve, reject) => {
new pdfreader.PdfReader().parseFileItems(pp, (err, item) => {
if (err) {
reject(err)
} else if (!item) {
resolve()
} else {
itemHandler(item)
}
})
})
let pages = []
promisifiedParseFileItems(pp, item => {
if (item.page) {
pages.push(lines)
rows = {}
} else if (item && item.text) {
// accumulate text items into rows object, per line
(rows[item.y] = rows[item.y] || []).push(item.text)
}
}).then(() => {
console.log("done", pages.length)
}, e => {
console.error("error", e)
})
注意:使用異步生成器你會(huì)得到更好的代碼,但是現(xiàn)在在這里解釋太多了,因?yàn)閺幕卣{(diào)到異步生成器的轉(zhuǎn)換沒有你想象的那么簡(jiǎn)單。

TA貢獻(xiàn)1765條經(jīng)驗(yàn) 獲得超5個(gè)贊
如果要鏈接 a then,則需要回調(diào)函數(shù)返回 Promise :
new pdfreader.PdfReader()
.parseFileItems(pp, function (err, item) {
return new Promise( (resolve, reject) => {
let pages = ...
// do stuff
resolve(pages);
}
})
.then( pages => {
console.log("done" + pages.length);
});
添加回答
舉報(bào)