在 Meteor 中,是不是可以从同步函数(与 wrapAsync 相反)创建异步函数?

Posted

技术标签:

【中文标题】在 Meteor 中,是不是可以从同步函数(与 wrapAsync 相反)创建异步函数?【英文标题】:In Meteor, is it possible to make an async function from a sync function (opposite of wrapAsync)?在 Meteor 中,是否可以从同步函数(与 wrapAsync 相反)创建异步函数? 【发布时间】:2020-09-09 05:18:52 【问题描述】:

我知道如何使用Meteor.wrapAsync(),使一个接受回调或返回一个承诺的函数像同步一样可用。

是否有可能做相反的事情,如果可以,如何做?我有一个服务器端函数,可以同步调用一些 Meteor 的东西(包括集合和帐户)。我希望能够使用p-allasync.js 之类的东西批量同时运行它,以处理数组中的项目并等待完成。

该应用正在使用 Meteor 1.6.0.1。

这是一些不起作用的代码,因为“Meteor 代码必须始终在 Fiber 中运行”:

  const actions = entries.map(entry =>
    () => new Promise((resolve, reject) =>
      Meteor.defer(() => 
        try 
          const result = createUserFromEntry(entry, schoolId, creatorId, recordTypeId, signupYmd);
          resolve(result);
         catch (exc) 
          reject(exc);
        
      )
    )
  );
  Meteor.wrapAsync(callback =>
    pAll(actions,  concurrency: 8, stopOnError: false )
      .then(res => callback(null, res))
      .catch(err => callback(err, null))
  )();

也欢迎提出在 Meteor 中实现相同目标的不同/正确方法的建设性建议。

【问题讨论】:

【参考方案1】:

Meteor.defer 要求传递的函数在纤程中运行。这可以使用Meteor.bindEnvironment 修复:

Meteor.defer(Meteor.bindEnvironment(function () 
  try 
    const result = createUserFromEntry(entry, schoolId, creatorId, recordTypeId, signupYmd);
    resolve(result);
   catch (exc) 
    reject(exc);
  
))

p-all 函数不需要包装,因为它已经是异步的:

Meteor.startup(async function () 
 const done = await pAll(actions,  concurrency: 8, stopOnError: false )
)

但是,有一个不错的糖果可以让你在同步函数中运行异步代码,只要你在一个纤程中,使用Promise.await

Meteor.startup(function () 
 const done = Promise.await(pAll(actions,  concurrency: 8, stopOnError: false ))
)

请注意,Promise.await 是 Meteor 特定的,仅在服务器上可用。

【讨论】:

以上是关于在 Meteor 中,是不是可以从同步函数(与 wrapAsync 相反)创建异步函数?的主要内容,如果未能解决你的问题,请参考以下文章

Meteor 的 DDP 在同步非常大的集合方面的效率如何?

Meteor:Minimongo 不与 MongoDB 同步

如何使 Meteor 方法同步?

Meteor JS 框架是不是与 Google App Engine 兼容?

fs.readFileSync 不是 Meteor 的函数,React

在 Meteor 中使用 fs 模块获取未捕获的 TypeError _fs2.default.readFile 不是函数