This question already has an answer here:
这个问题在这里已有答案:
- Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference 6 answers
- 为什么我的变量在函数内部修改后没有变化? - 异步代码参考6个答案
I have the following Javascript and I am trying to access the content data out of the service scope, what's the best way to access that data?
我有以下Javascript,我试图从服务范围访问内容数据,访问该数据的最佳方式是什么?
Service
.getContent()
.then((content = {}) => {//access this content out of 'Service' scope})
.catch((error = {}) => {console.log('errror', error)})
I tried the following:
我尝试了以下方法:
let data = null;
Service
.getContent()
.then((content = {}) => {data = content})
.catch((error = {}) => {console.log('errror', error)})
console.log(data);
But I get the error that data is undefined. How can I get the contents of content to data
但我得到数据未定义的错误。如何将内容的内容提供给数据
1 个解决方案
#1
3
You can't do it this way. The issue is that a .then()
handler is called at some indeterminate time in the future. It's always called at least on the next tick of the event loop (per the promise specification) and if there's a real asynchronous operation behind the promise, then who knows when it will be called (it could be ms to hours to never).
你不能这样做。问题是在将来某个不确定的时间调用.then()处理程序。它总是至少在事件循环的下一个滴答中被调用(根据promise规范),如果在promise后面有一个真正的异步操作,那么谁知道它什么时候被调用(它可能是ms到几小时永远不会)。
The ONLY way you can possibly know when it gets called and thus when a value provided in the .then()
handler is available is by using the data it provides inside the .then()
handler itself or by calling some function from within the .then()
handler and passing the data to it.
你可以知道它被调用的唯一方式,也就是当.then()处理程序中提供的值可用时,可以使用它在.then()处理程序本身内提供的数据,或者通过调用其中的某个函数。 then()处理程序并将数据传递给它。
Your console.log(data)
statement always runs BEFORE the .then()
handler is called. That's why you can't use the variable there. And, the only place you actually know when the data is available is inside the .then()
handler so that's where you need to consume the data.
您的console.log(data)语句始终在调用.then()处理程序之前运行。这就是为什么你不能在那里使用变量。而且,您实际知道数据何时可用的唯一位置是.then()处理程序内部,因此您需要使用数据。
This is a different way of thinking about coding. It's the asynchronous model that Javascript uses for lots of things and you do need to learn it in order to be successful with Javascript.
这是一种考虑编码的不同方式。这是Javascript用于很多事情的异步模型,你需要学习它才能使用Javascript成功。
So, the proper way to do things is this:
所以,正确的做法是这样的:
Service.getContent().then((content = {}) => {
// use content here
console.log(content);
}).catch(err => {
// handle error here
console.log('errror', err)
});
FYI, ES7 allows you to use await
to make your code "look" a little more synchronous. It's important to understand how the actual asynchronous model works, even when using await
. But, in your example, you could do this:
仅供参考,ES7允许您使用等待使您的代码“看起来”更加同步。了解实际异步模型的工作原理非常重要,即使使用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
});
An important thing to understand is that while await
appears to "block" the function execution until the promise resolves and makes it look like you can program synchronously again even with async operations, this is only partially true. The function execution itself is still asynchronous. In fact, as soon as you call await Service.getContent()
, your function someFunction()
returns a promise and any code after that function is called keeps on executing. So, the whole program flow is not blocked, only the internals of someFunction()
are blocked waiting on that promise. await
is really just syntactical sugar for .then()
. The underlying concepts are still the same. And, functions still return immediately as soon as you await
an asynchronous operation.
需要理解的重要一点是,await似乎会“阻止”函数执行,直到promise解析为止,即使使用异步操作也可以再次同步编程,这只是部分正确。函数执行本身仍然是异步的。实际上,只要调用await Service.getContent(),你的函数someFunction()就会返回一个promise,并且在调用该函数之后的任何代码都会继续执行。因此,整个程序流程都没有被阻止,只有someFunction()的内部被阻塞等待该promise。 await实际上只是.then()的语法糖。基本概念仍然相同。并且,一旦等待异步操作,函数仍会立即返回。
You can only use await
inside an async
function and all function declared async
return a promise. So, the promise is still being used, await
just gives you a bit more way to write code inside a function.
您只能在异步函数中使用await,并且所有声明为异步的函数都会返回一个promise。因此,承诺仍在使用中,等待只是为您提供了一种在函数内部编写代码的方法。
#1
3
You can't do it this way. The issue is that a .then()
handler is called at some indeterminate time in the future. It's always called at least on the next tick of the event loop (per the promise specification) and if there's a real asynchronous operation behind the promise, then who knows when it will be called (it could be ms to hours to never).
你不能这样做。问题是在将来某个不确定的时间调用.then()处理程序。它总是至少在事件循环的下一个滴答中被调用(根据promise规范),如果在promise后面有一个真正的异步操作,那么谁知道它什么时候被调用(它可能是ms到几小时永远不会)。
The ONLY way you can possibly know when it gets called and thus when a value provided in the .then()
handler is available is by using the data it provides inside the .then()
handler itself or by calling some function from within the .then()
handler and passing the data to it.
你可以知道它被调用的唯一方式,也就是当.then()处理程序中提供的值可用时,可以使用它在.then()处理程序本身内提供的数据,或者通过调用其中的某个函数。 then()处理程序并将数据传递给它。
Your console.log(data)
statement always runs BEFORE the .then()
handler is called. That's why you can't use the variable there. And, the only place you actually know when the data is available is inside the .then()
handler so that's where you need to consume the data.
您的console.log(data)语句始终在调用.then()处理程序之前运行。这就是为什么你不能在那里使用变量。而且,您实际知道数据何时可用的唯一位置是.then()处理程序内部,因此您需要使用数据。
This is a different way of thinking about coding. It's the asynchronous model that Javascript uses for lots of things and you do need to learn it in order to be successful with Javascript.
这是一种考虑编码的不同方式。这是Javascript用于很多事情的异步模型,你需要学习它才能使用Javascript成功。
So, the proper way to do things is this:
所以,正确的做法是这样的:
Service.getContent().then((content = {}) => {
// use content here
console.log(content);
}).catch(err => {
// handle error here
console.log('errror', err)
});
FYI, ES7 allows you to use await
to make your code "look" a little more synchronous. It's important to understand how the actual asynchronous model works, even when using await
. But, in your example, you could do this:
仅供参考,ES7允许您使用等待使您的代码“看起来”更加同步。了解实际异步模型的工作原理非常重要,即使使用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
});
An important thing to understand is that while await
appears to "block" the function execution until the promise resolves and makes it look like you can program synchronously again even with async operations, this is only partially true. The function execution itself is still asynchronous. In fact, as soon as you call await Service.getContent()
, your function someFunction()
returns a promise and any code after that function is called keeps on executing. So, the whole program flow is not blocked, only the internals of someFunction()
are blocked waiting on that promise. await
is really just syntactical sugar for .then()
. The underlying concepts are still the same. And, functions still return immediately as soon as you await
an asynchronous operation.
需要理解的重要一点是,await似乎会“阻止”函数执行,直到promise解析为止,即使使用异步操作也可以再次同步编程,这只是部分正确。函数执行本身仍然是异步的。实际上,只要调用await Service.getContent(),你的函数someFunction()就会返回一个promise,并且在调用该函数之后的任何代码都会继续执行。因此,整个程序流程都没有被阻止,只有someFunction()的内部被阻塞等待该promise。 await实际上只是.then()的语法糖。基本概念仍然相同。并且,一旦等待异步操作,函数仍会立即返回。
You can only use await
inside an async
function and all function declared async
return a promise. So, the promise is still being used, await
just gives you a bit more way to write code inside a function.
您只能在异步函数中使用await,并且所有声明为异步的函数都会返回一个promise。因此,承诺仍在使用中,等待只是为您提供了一种在函数内部编写代码的方法。