【发布时间】:2018-05-19 18:17:38
【问题描述】:
我有一个 es6 类,有一个 init() 方法负责获取数据、转换它,然后用新转换的数据更新类的属性 this.data。
到目前为止,一切都很好。
类本身有另一个getPostById() 方法,只是做它听起来的样子。这是该类的代码:
class Posts {
constructor(url) {
this.ready = false
this.data = {}
this.url = url
}
async init() {
try {
let res = await fetch( this.url )
if (res.ok) {
let data = await res.json()
// Do bunch of transformation stuff here
this.data = data
this.ready = true
return data
}
}
catch (e) {
console.log(e)
}
}
getPostById(id){
return this.data.find( p => p.id === id )
}
}
直截了当,除了我在init() 方法中有一个async/await 机制。
现在,这段代码可以正常工作了:
let allPosts = new Posts('https://jsonplaceholder.typicode.com/posts')
allPosts.init()
.then( d => console.log(allPosts.getPostById(4)) )
// resulting Object correctly logged in console
但它只会打印到控制台中:
我如何将allPosts.getPostById(4) 用作函数的return?
喜欢:
let myFunc = async () => {
const postId = 4
await allPosts.init() // I need to wait for this to finish before returning
// This is logging correct value
console.log( 'logging: ' + JSON.stringify(allPosts.getPostById( postId ), null, 4) )
// How can I return the RESULT of allPosts.getPostById( postId ) ???
return allPosts.getPostById( postId )
}
myFunc() 返回 Promise 但不是最终值。我已经阅读了有关该主题的几篇相关帖子,但它们都给出了日志记录的示例,永不返回。
Here is a fiddle 包括两种处理init() 的方法:使用Promise 和使用async/await。无论我尝试什么,我都无法使用getPostById(id) 的最终值。
这篇文章的问题是:我怎样才能创建一个函数来返回getPostById(id) 的值?
编辑:
很多很好的答案试图解释 Promises 与主执行循环有关。 经过大量的视频和其他好的阅读,这是我现在所理解的:
我的函数init() 正确返回。然而,在主事件循环中:它返回 a Promise,然后我的工作是从 kinda 并行循环(不是新的真实线)。为了从并行循环中捕获结果,有两种方法:
使用
.then( value => doSomethingWithMy(value) )使用
let value = await myAsyncFn()。现在这是愚蠢的打嗝:
await 只能在
async函数中使用:p
因此它本身返回一个 Promise,可与 await 一起使用,它应该嵌入到 async 函数中,该函数将可与 await 等一起使用...
这意味着我们不能真正等待 Promise:相反,我们应该无限期地捕获并行循环:使用 .then() 或 async/await。
感谢您的帮助!
【问题讨论】:
-
见:stackoverflow.com/questions/14220321/… 基本上,你不能。你要么等待承诺,要么在异步函数中使用
await。 -
在
await allPosts之后的console.log 中是否可以看到allPosts.data? -
@NanduKalidindi yes
console.log(allPosts.data)将正确的值打印到控制台。但是,仍然可以返回它。 @Mark_M 是的,我读过这篇文章,但恐怕这个问题并没有得到真正的回答:它只是嵌入了关于异步代码的课程......我需要变得更实用一些。如果你告诉我这是不可能的:如果我们不能使用它们的结果,为什么还存在 Promises?啊哈哈 -
我不确定你是否理解 Promise,你不能返回一个值,因为该值取决于调用你的函数时尚不可用的东西。这就是为什么你可以使用回调和承诺,函数必须返回一些东西,所以它返回一个可以解析或拒绝的值的承诺。
async await语法表明函数等待,但实际上它没有,async函数总是返回一个承诺。 -
@HMR 我会说使用
await的函数代码确实会等待,但函数的调用者 不会。 (它必须使用await(或then)本身)。
标签: javascript ecmascript-6 async-await