所以我一直在摆弄 javascript
并发现了一个奇怪的行为,无论如何。
给定这些片段
database.js
import MongoDB from "mongodb";
const MongoClient = MongoDB.MongoClient;
const uri = "mongodb://127.0.0.1:27017/?poolSize=20&writeConcern=majority"
const mongoClient = new MongoClient(uri, { useUnifiedTopology: true });
let instance;
const getInstance = async () => {
if (!instance) {
instance = mongoClient.connect();
}
return instance;
}
export const client = await getInstance();
services.js
import { client } from "./database"
//return array of items
function getUserRecommendationItems(username) {
const shopifyDb = client.db('Shopify');
const product = shopifyDb.collection('product');
return product.find().toArray();
}
export default { getUserRecommendationItems }
index.js
import services from "./services"
(async () => {
const products = await services.getUserRecommendationItems();
console.log(products);
})();
当我删除 database.js
中的 await 时,它会抛出错误,因为它需要先等待客户端连接。
我的问题是,为什么我可以访问 client
中的 service.js
而不将它放在异步函数中?
这是否意味着导出和导入是引擎盖下的异步函数?
答案 0 :(得分:2)
您的环境似乎支持 the top-level await proposal。该提案目前处于第 4 阶段,这意味着“完成”并可以正式包含在规范中。但支持可能仍会有所不同。
<块引用>顶级 await
让我们依靠模块系统本身来处理所有这些承诺,并确保事情得到很好的协调。上面的例子可以简单地编写和使用如下:
// awaiting.mjs
import { process } from "./some-module.mjs";
const dynamic = import(computedModuleSpecifier);
const data = fetch(url);
export const output = process((await dynamic).default, await data);
// usage.mjs
import { output } from "./awaiting.mjs";
export function outputPlusValue(value) { return output + value }
console.log(outputPlusValue(100));
setTimeout(() => console.log(outputPlusValue(100), 1000);
在 usage.mjs
中的 await
的 Promise 得到解决之前,awaiting.mjs
中的所有语句都不会执行,因此在设计上避免了竞争条件。这是一个扩展,如果 awaiting.mjs
没有使用顶级 await
,那么 usage.mjs
中的任何语句都不会执行,直到 awaiting.mjs
被加载并且它的所有语句已执行。
因为您在 await
中有一个顶级 database.js
,所以 services.js
只会在该模块的 client
承诺得到解决时才会执行。