Meteor 代码必须始终在 Fiber 中运行

问题描述 投票:0回答:1

Meteor 代码产生了这个错误

packages\meteor.js:1260
(STDERR)     throw new Error("Meteor code must always run within a Fiber. " +

(STDERR) Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.

这是代码,不是在 Fiber 中运行。那为什么会出错呢?以及如何解决?请。谢谢

// ON THE SERVER

//methods.js
import {collectData} from './ad/server/logic';
Meteor.mothods({
  'collectData'(source, instrument) {
    instrument.forEach(function(item, index) {
      setTimeout(function(){
        collectData(item)
      }, 5000 * (index + 1));
    });
  },
})

//logic.js
import WebSocket from "ws";

async function collectData(instrument){
  let dt = moment().format('DD/MM/YYYY')
  try {
    scrap(instrument, dt)
  } catch (error) {
    console.log('scrap error: ', error)    
  }
}

function scrap(instrument, dt){
  //...
  socket.onmessage = function(message) {
    //...
    insertScrapedData(instrument, scrapedData)
  }
};

function insertScrapedData(VAL, scrapedData){
  if(VAL == 'XXX'){
    Meteor.bindEnvironment((callback) => {
      insertDocument('XXX', scrapedData, callback); // <<<<<<<<<< THE ERROR LINE <<<<<<<<<<
    }, (err) => {
      console.error('insert error', err);
    });
  }
}

function insertDocument(VAL, doc, callback) {
  if(VAL=='XXX) xxxCol.insert(doc, callback);
}
export {collectData}

meteor
1个回答
0
投票

问题是您的

setTimeout
处理程序和
socket.onmessage
回调都从 fiber 中脱离出来。您需要用
Meteor.bindEnvironment
包装这些回调,就像您在
insertScrapedData
中所做的那样。基本上,一旦你在纤维外面,你就不能再回来了,所以
Meteor.bindEnvironment
里的
insertScrapedData
是不够的。你需要确保你永远不会离开它。

既然

setTimeout
当然是一种非常常用的方法,Meteor 实际上提供了一个现成的版本,您可以在没有 bindEnvironment 的情况下使用: https://docs.meteor.com/api/timers.html#Meteor-setTimeout

© www.soinside.com 2019 - 2024. All rights reserved.