我有以下Javascript,并且我尝试从服务范围中访问内容数据,访问该数据的最佳方式是什么?
Service
.getContent()
.then((content = {}) => {//access this content out of 'Service' scope})
.catch((error = {}) => {console.log('errror', error)})
我尝试了以下内容:
let data = null;
Service
.getContent()
.then((content = {}) => {data = content})
.catch((error = {}) => {console.log('errror', error)})
console.log(data);
但是我得到数据未定义的错误。如何将内容的内容转换为数据
答案 0 :(得分:4)
你不能这样做。问题是在将来某个不确定的时间调用.then()
处理程序。它总是至少在事件循环的下一个滴答中被调用(根据promise规范),如果在promise之后有一个真正的异步操作,那么谁知道它什么时候被调用(它可能是ms)从来没有几个小时。
您可能知道它被调用的唯一方式,因此当.then()
处理程序中提供的值可用时,可以使用它在.then()
处理程序本身内提供的数据,或者通过调用一些从.then()
处理程序中运行并将数据传递给它。
您的console.log(data)
语句始终在调用.then()
处理程序之前运行。这就是为什么你不能在那里使用变量的原因。并且,您实际知道数据何时可用的唯一位置是.then()
处理程序内部,以便您需要使用数据。
这是一种考虑编码的不同方式。它是Javascript用于许多事情的异步模型,你需要学习它才能使用Javascript成功。
所以,正确的做法是:
Service.getContent().then((content = {}) => {
// use content here
console.log(content);
}).catch(err => {
// handle error here
console.log('errror', err)
});
仅供参考,ES7允许您使用await
制作代码"外观"多一点同步。了解实际异步模型的工作原理非常重要,即使使用await
也是如此。但是,在您的示例中,您可以这样做:
async function someFunction() {
try {
let content = await Service.getContent();
// use content here
console.log(content);
return someValue;
} catch(e) {
// handle error here
console.log('errror', err)
return someOtherValue;
}
}
someFunction().then(val => {
// do something with val here
});
要理解的一件重要事情是await
出现在"阻止"函数执行直到promise解析并使它看起来像你可以再次同步编程,即使使用异步操作,这只是部分正确。函数执行本身仍然是异步的。实际上,只要调用await Service.getContent()
,函数someFunction()
就会返回一个promise,并且在调用该函数之后的任何代码都会继续执行。因此,整个程序流程都没有被阻止,只有someFunction()
的内部被阻止等待该承诺。 await
实际上只是.then()
的语法糖。基本概念仍然相同。并且,只要您await
进行异步操作,函数就会立即返回。
您只能在await
函数中使用async
,并且所有声明为async
的函数都会返回一个promise。因此,承诺仍在使用中,await
只是为您提供了一种在函数内部编写代码的方法。