Javascript - 访问变量然后在它的范围之外

时间:2018-04-06 17:53:20

标签: javascript es6-promise

我有以下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);

但是我得到数据未定义的错误。如何将内容的内容转换为数据

1 个答案:

答案 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只是为您提供了一种在函数内部编写代码的方法。