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}
问题是您的
setTimeout
处理程序和 socket.onmessage
回调都从 fiber 中脱离出来。您需要用 Meteor.bindEnvironment
包装这些回调,就像您在 insertScrapedData
中所做的那样。基本上,一旦你在纤维外面,你就不能再回来了,所以Meteor.bindEnvironment
里的insertScrapedData
是不够的。你需要确保你永远不会离开它。
既然
setTimeout
当然是一种非常常用的方法,Meteor 实际上提供了一个现成的版本,您可以在没有 bindEnvironment 的情况下使用:
https://docs.meteor.com/api/timers.html#Meteor-setTimeout