在自定义承诺上使用异步等待
Posted
技术标签:
【中文标题】在自定义承诺上使用异步等待【英文标题】:Using async await on custom promise 【发布时间】:2018-03-14 23:45:47 【问题描述】:我试图在一个返回承诺的函数上使用异步等待,但我得到的输出是 Promise <pending>
。在这里,我使用了一个名为 convertFiletoPDF 的函数,它返回一个承诺。我需要得到输出(我在 resolve() 中提到的路径)。
当我使用它时
convertFiletoPDF(file).then((result) =>
console.log(result);
).catch((err)=>
console.log(err);
);
它给出了预期的结果。下面的代码有什么问题?我对这些异步等待和承诺很陌生。
function convertFiletoPDF(file)
return new Promise(function(resolve, reject)
unoconv.convert(file, "pdf", function(
err,
result
)
if (err)
reject(err);
let File = file.substring(file.lastIndexOf("/")+1,file.lastIndexOf("."));
// result is returned as a Buffer
fs.writeFile(__dirname+"/files/converted/"+File+".pdf", result, error =>
/* handle error */
if (err) reject(error);
else resolve("./files/converted/"+File+".pdf");
);
);
);
async function myfunc(file)
let res = await convertFiletoPDF(file);
return res;
let res = myfunc(file);
console.log(res);
【问题讨论】:
【参考方案1】:async
函数的返回值是一个承诺,所以很自然这就是你的console.log
输出的值。您需要通过await
(在另一个async
函数内)或使用then
/catch
(在另一个async
函数内)使用结果。
这是你目前正在做的事情:
function convertFiletoPDF(file)
return new Promise(function(resolve, reject)
setTimeout(resolve, 400, "Done");
);
async function myfunc(file)
let res = await convertFiletoPDF(file);
return res;
let res = myfunc("some file");
console.log(res);
您需要这样做:
function convertFiletoPDF(file)
return new Promise(function(resolve, reject)
setTimeout(resolve, 400, "Done");
);
async function myfunc(file)
let res = await convertFiletoPDF(file);
return res;
(async() =>
try
let res = await myfunc("some file");
console.log(res);
catch (e)
// Deal with the fact there was an error
)();
或使用then
和catch
:
function convertFiletoPDF(file)
return new Promise(function(resolve, reject)
setTimeout(resolve, 400, "Done");
);
async function myfunc(file)
let res = await convertFiletoPDF(file);
return res;
myfunc("some file")
.then(res =>
console.log(res);
)
.catch(e =>
// Deal with the fact there was an error
);
【讨论】:
【参考方案2】:convertFiletoPDF()
这个函数运行并返回一个 Promise。这很好。
myfunc()
假设myfunc
需要 10 秒。 javascript 开始通过event loop
机制等待来自libuv
的新创建线程结果。所以,Javascript 说,“那是异步的,我不会等待,当它完成时它会通知我,我将运行我的 then
回调,然后我将继续它的输出。”
Javascript 信守诺言。尝试在下一行运行。 myFunch
仍在工作。输出还没有准备好。返回未定义。
let res = myfunc(file);
console.log(res);
你没有定义。
【讨论】:
【参考方案3】:有人可能会从我的代码中发现这个示例很有用。您可以将其包装在一个 Promise 中,然后解析自定义 Promise,然后调用另一个 Promise 以确认收到原始 web3 调用。
return new Promise((resolve, reject) =>
tokenContract.methods.approve(
exchangeAddress,
BIG_NUMBER_1e50
)
.send( from )
.once('transactionHash')
.once('receipt', receipt => resolve(receipt))
.on('confirmation')
.on('error', err => reject(err))
.then( receipt => // will be fired once the receipt its mined
console.log(receipt),
);
);
【讨论】:
以上是关于在自定义承诺上使用异步等待的主要内容,如果未能解决你的问题,请参考以下文章
异步等待承诺上的 UnhandledPromiseRejectionWarning