美文网首页让前端飞
ES6模块如何export异步操作结果

ES6模块如何export异步操作结果

作者: 太平洋的微风 | 来源:发表于2017-09-08 14:35 被阅读0次

组织ES6模块的时候,一般情况下我们export一些基本类型的变量,复合类型的对象或者函数等等。但有时模块内的代码也会出现异步操作,我们希望模块可以把异步操作的结果export出来供另一个模块调用。这种情况下应该怎么写呢?本文列举两种方法供参考。

利用Promise对象

export导出的变量类型可以是任意的Javascript对象,那么我们可以利用Promise对象帮助我们代理异步操作,将Promise对象导出,在导入Promise的地方添加成功/失败的回调即可。

a.js

import {AsyncStorage} from 'react-native';
export async function getVariable() {
    let variable = await AsyncStorage.getItem("variable");
    return variable;
}

b.js

import {getVariable} from 'a.js';
getVariable().then(v=>{
    //在这里获得模块a真正想导出的值
}).catch(e=>{})

a文件中使用了ES7的async函数,async函数一旦执行会立即返回一个Promise对象,等待所有await后的异步操作结束后改变Promise的状态。如果不使用async await,a文件也可以这样写:

import {AsyncStorage} from 'react-native';
export function getVariable() {
    return new Promise((resolve, reject)=>{
        AsyncStorage.getItem("variable").then(v=>{
            resolve(v);
        }).catch(e=>{
            reject(e);
        })
    })
}

直接导出异步结果

a.js

import {AsyncStorage} from 'react-native';
export var variable;

AsyncStorage.getItem("variable").then(v=>{
    variable = v;  //在回调函数中修改导出变量variable
}).catch(e=>{});

b.js

import {variable} from 'a.js';

console.log(variable);   //undefined

setTimeout(()=>{
    console.log(variable);   //异步操作所获得的值
}, 1000)

需要注意的是,当采用这种方式时,要注意导出变量会发生变化,在引用模块中要特别注意,否则突变的值会对程序造成莫名的bug。

说明

能够使用上述两种方式导出异步操作的结果,原因就在于,ES6的模块与CommonJS是不同的。

CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。

阮一峰的ES6入门有如下详细的说明:

CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。换句话说,ES6 的import有点像 Unix 系统的“符号连接”,原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。

相关文章

网友评论

    本文标题:ES6模块如何export异步操作结果

    本文链接:https://www.haomeiwen.com/subject/jgggjxtx.html