为什么这会在异步函数之外等待?

时间:2021-06-02 05:30:20

标签: javascript node.js mongodb asynchronous

所以我一直在摆弄 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 而不将它放在异步函数中? 这是否意味着导出和导入是引擎盖下的异步函数?

1 个答案:

答案 0 :(得分:2)

您的环境似乎支持 the top-level await proposal。该提案目前处于第 4 阶段,这意味着“完成”并可以正式包含在规范中。但支持可能仍会有所不同。

Quoting the proposal

<块引用>

顶级 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 承诺得到解决时才会执行。

相关问题