2016-04-14 112 views
0

所以我很難讓模塊返回我想要的值。基本上它會查看我的文件系統並返回最後創建的GIF文件。如果沒有GIF,它會查找PPM(另一種文件類型)並生成一個GIF並返回該文件。如果沒有PPM,它會查看MySQL數據庫並根據其中的內容生成GIF。所有這些工作正常。JavaScript/Node.js + Express - 函數返回undefined之前完成

該模塊被稱爲與Express中一個HTTP請求,其中currentImg()被調用模塊:

//REQUEST CURRENT IMAGE 
app.get('/img', function(req, res) { 
    console.log(currentImg()); 
}); 

此請求總是返回 '未定義'。我已經嘗試了一些調試,模塊在module.exports函數中的'queryDatabase(returnFile)'行返回之前返回'undefined'。

// CurrentImg 

module.exports = function() { 
    imageFile = ""; 
    queryDatabase(returnFile); 
    return imageFile; 
} 

function queryDatabase(callback) { 
    imageFile = ""; 
    client.query("SHOW TABLES FROM mathsDB", function(err, result) { 
      if (err) 
        console.log(err); 
      else 
        currentImage = result[result.length - 1]["Tables_in_mathsDB"]; 
        currentImage = currentImage.substring(5); 
        callback; 
    }); 
} 

function returnFile() { 
    fs.stat("./img/image" + currentImage + ".gif", function(err, stat) { 
      if (err==null) { 
        imageFile = "/img/image" + currentImage + ".gif"; 
        return imageFile; 
      } 
      else { 
        fs.stat("./img/image" + currentImage + ".ppm", function(err, stat) { 
          if (err==null) { 
            convert.convert("image" + currentImage); 
            imageFile = "/img/image" + currentImage + ".gif"; 
            return imageFile; 
          } 

          else { 
            exportPPM.make(); 
            setTimeout(waitConvert, 500); 
            function waitConvert() { 
              convert.convert("image" + currentImage); 
              imageFile = "/img/image" + currentImage + ".gif"; 
              return imageFile; 
            } 
          } 
        }); 
      } 
    }); 
} 

我試過做一些閱讀回調,就像你可以在我的代碼中看到的,但是這似乎並沒有解決任何問題。我已經讀過一些承諾,但他們似乎也沒有提供一個可靠的解決方案。

任何人都可以提供一個指向正確方向的指針,讓它以非阻塞的方式運行嗎?

謝謝。

+2

'callback;'實際上沒有做任何事情。您需要調用它,就像其他功能一樣。 – SLaks

+0

http://blog.slaks.net/2015-01-04/async-method-patterns/ – SLaks

+0

由於returnFile()將需要等待queryDatabase完成..您可以使用async.waterfall在系列函數之後運行一個函數另一個。 https://github.com/caolan/async#waterfall – FRizal

回答

0

使用異步瀑布來一個接一個地串聯運行函數。 https://github.com/caolan/async#waterfall。 所以像這樣的東西。

async.waterfall([ 
function (callback) { 
imageFile = ""; 
client.query("SHOW TABLES FROM mathsDB", function(err, result) { 
     if (err) 
       console.log(err); 
     else 
       currentImage = result[result.length - 1]["Tables_in_mathsDB"]; 
       currentImage = currentImage.substring(5); 
       callback(currentImage) 
}); 

}, 

    function(currentImage, callback) { 
     // arg1 now equals 'one' and arg2 now equals 'two' 
     fs.stat("./img/image" + currentImage + ".gif", function(err, stat) { 
      if (err==null) { 
        imageFile = "/img/image" + currentImage + ".gif"; 
        return imageFile; 
      } 
      else { 
        fs.stat("./img/image" + currentImage + ".ppm", function(err, stat) { 
          if (err==null) { 
            convert.convert("image" + currentImage); 
            imageFile = "/img/image" + currentImage + ".gif"; 
            return imageFile; 
          } 

          else { 
            exportPPM.make(); 
            setTimeout(waitConvert, 500); 
            function waitConvert() { 
              convert.convert("image" + currentImage); 
              imageFile = "/img/image" + currentImage + ".gif"; 
              return imageFile; 
            } 
          } 
        }) 
      } 
    callback(null,currentImage) }) 


    } 

], function (err, currentImage) { 
    console.log(currentImage); 
}); 
+0

感謝您的回覆。我已經閱讀了Async的文檔,雖然它看起來應該可以工作,但我覺得我的問題應該可以通過使用本地JS解決。我不相信爲每一個小實用程序或功能導入一個新庫,但其他人可能會認爲這是可以接受的。謝謝! –

+0

異步實用程序將有望在ES7中。如果您需要通過當前的ES6解決它,請參閱Promise.all。相應地重複這兩個函數。 – FRizal