2016-12-01 64 views
-1

編輯:「線程」+「異步」模塊不是異步(如果不是線程)安全!它被另一個異步函數調用!這就是爲什麼線程在單個異步完成之前運行兩次。有一些代碼剩餘部分異步調用相同的代碼。回調在async.map中已經被調用

下面是一些代碼,給出了錯誤(標有ERROR!):

async.map(threads, function (thread, cb_) { 
      zz++, 
      console.log(zz); 
      (function (id____) { 

       thread.msg({ cmd: "compare", data: id____ }, function (result) { 
        if (result) 
         compareCheck = false; 
        console.log(cb_.toString()); 

        // ERROR! 
        cb_(null, thread); // why? 
        // return cb_ doesn't solve neighter 

       }); 
      })(id__); 

     }, function (err, result) { 

      if (compareCheck) { 
       console.log("b:" + Session.cmpCtr); 

       threads[Session.cmpCtr % nThreads].msg({ 
        cmd: "add", data: id__ 
       }, function (response) { 
        setImmediate( cbCmp_); 
       }); 
      } 
      else { 

       // whatsoever gives collision, retry new one, 
       // setImmediate to stop recursion fee on cpu 
       setImmediate(function() { 

        id__ = ""; 
        for (var i = 0; i < 24; i++) 
         id__ += rndChar(); 
        cmpId(id__, cbCmp_); 
       }); 
      } 
     }); 

這段代碼做什麼,檢查是否N個線程(使用線程模塊與重生)在自己的列表中有一個會話變量等於新生成的一個,那麼如果不存在衝突,則將該新變量添加到線程列表中的一個。如果一個線程的命令是「add」,那麼它會將變量添加到列表中,如果命令是「compare」,那麼它將根據列表的值和新值在回調中給出真正的錯誤值。

爲什麼async.map會給出這個錯誤?該函數是由所有線程執行的,爲什麼它不應該被執行多次?這是一個回調。

也許async.map不能有一個線程列表(不可序列化),只是複製它以在每個會話變量生成時擁有更多的多個實例?

線程正在使用由與初始化的包裝:

threads.push(new QThread(function (input, done) { 
    this.data = (typeof this.data === "undefined")? [] : this.data; 
    if (input.cmd != null && typeof input.cmd !== "undefined") { 
     if (input.cmd === "add") { 
      data.push(input.data); 
      done(true); 
     } 
     else if (input.cmd === "compare") 
     { 
      for (var i = 0; i < data.length; i++) { 
       if (data[i] == input.data) { 
        done(true); 
        return; 
       } 
      } 

      done(false); 
      return; 
     } 
    } 
})); 

編輯:return cb_(null, thread);給出同樣的錯誤。

我想使用async.map,因爲使用簡單的自旋鎖樣式同步是cpu資源密集型,並且不適合nodejs。

下面是輸出錯誤:

C:\...\async.js:985 
     if (fn === null) throw new Error("Callback was already called."); 
         ^

Error: Callback was already called. 
    at C:\...\async.js:985:32 
    at C:\...\async.js:1158:13 
    at C:\...\session.js:79:28 
    at Worker.<anonymous> (C:\...\qthread.js:25:13) 
    at Worker.emit (C:\...\index.js:129:35) 
    at Worker.handleMessage (C:\Users\pc\node_modules\threads\lib\worker.node\worker.js:119:17) 
    at emitTwo (events.js:106:13) 
    at ChildProcess.emit (events.js:191:7) 
    at process.nextTick (internal/child_process.js:744:12) 
    at _combinedTickCallback (internal/process/next_tick.js:67:7) 

回答

1

被稱爲cb_(null, thread);後,功能將依然執行剩下的代碼。這是更好地終止回調這樣

return cb_(null, thread);

這可確保在調用回調,將停止執行,返回的東西。

+0

return cb_(null,thread);在同一行上出現同樣的錯誤 –

+0

在你呼叫回叫的地方放置'return'。 – kawadhiya21

+0

我把文件中的所有回調都放回去了,還是一樣的錯誤同一行。 –