2014-12-03 149 views
0

不定值:承諾不會返回對象數組

我使用Q管理與Node.js的承諾,我使用easyImage處理圖像。

這段代碼工作正常,它加載,保存,剪切tmp文件夾中的圖像並將其粘貼到用戶文件夾中。我唯一的問題是將最終數據保存到數據庫。我得到了一個未定義值的數組中......

exports.postAccountImages = function(req, res, next) { 
    User.findById(req.user.id, function(err, user) { 
    var path = __dirname + '/../public/images/u/' + user._id + '/'; 
    var max = 800; 
    fs.exists(path, function(exists) { 
     if (!exists) fs.mkdirSync(path); 
    }); 

    var promises = []; 
    for (var key in req.files) { 
     if (req.files.hasOwnProperty(key)) { 
     (function(file) { 
      q().then(function() { 
      return promises.push(easyimg.info(file.path).then(function(image) { 
       easyimg.resize({ 
       src: file.path, 
       dst: path + file.name, 
       width: (image.width >= max) ? max : image.width, 
       height: (image.height >= max) ? max : image.height, 
       quality: 80 
       }).then(function(image) { 
       fs.remove('./tmp-uploads/' + image.name); 
       return { 
        src: image.name, 
        main: false 
       }; 
       }); 
      })); 
      }); 
     })(req.files[key]); 
     } 
    } 

    q.all(promises).then(function(result) { 
     console.log(result); // [undefined, undefined, undefined, ...] 
     // Here I should push result to the DB 
    }); 
    }); 
}; 
+2

您需要對承諾和異步回調進行一些學習。這個答案可能會幫助你:http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call。一般來說,您必須在異步回調中「使用」異步結果,而不是其他任何地方。 – jfriend00 2014-12-03 22:27:36

+0

我確信我必須瞭解承諾,但是從您發佈的鏈接中,我不太確定我應該如何處理。 它用jQuery解釋了一些東西......我用Express和Node ...問題是:我怎樣才能得到回報? – 2014-12-03 22:31:13

+0

我可以根據我的問題舉個例子嗎? – 2014-12-03 22:52:38

回答

1

下面是如何做到這一點的一般概念(未經測試):

var promises = []; 
for (var key in req.files) { 
    if (req.files.hasOwnProperty(key)) { 
     (function(file) { 
      promises.push(easyimg.info(file.path).then(function(image) { 
       return easyimg.resize({ 
        src: file.path, 
        dst: path + file.name, 
        width: Math.max(image.width, 800), 
        height: Math.max(image,height, 800), 
        quality: 80 
       }).then(function(image) { 
        fs.remove('./tmp-uploads/' + image.name, function(err) { 
         if (err) { 
          // logging error, but not stopping execution 
          // since this is a non-fatal error 
          console.log("err removing temp upload: ", err); 
         } 
        }); 
        return {src: file.name, main: false}; 
       }); 
      })); 
     })(req.files[key]); 
    } 
} 
// now wait for all promises to finish 
// assumes you want to call next() no matter what when all image processing is done 
Promise.all(promises).then(function(results) { 
    // all results are in the results array here 
    // do whatever processing of the results array you want to do here 
    res.sendStatus(200); 
    next(); 
}, function() { 
    // set some status to send when there's an error 
    res.sendStatus(xxx); 
    next(); 
}); 

我糾正一些問題,並提出了一些改進:

  1. 當處理多個文件時,您的變量file被覆蓋,因爲您嘗試在多個異步回調中使用相同的變量。我把它放到一個閉包中,因此它被分別保存到每個正在處理的圖像中。這可能是使其不能處理多個圖像的主要問題。

  2. 你沒有在所有正確的時間呼叫next()(有時稱它太多次)。

  3. 你的錯誤處理有多個問題,因爲你不能只是返回一個異步方法來停止處理。

  4. 我決定,如果你不能刪除處理應該繼續而不是中止的臨時文件,因爲這不是一個致命的問題。

  5. 此代碼使用Promise.all()在完成所有操作而不是使用手動計數器時獲得回調。這也使錯誤處理更簡單。

+0

謝謝,它幫助我管理整個過程,並且我看到我需要學習承諾,我仍然在學習,而且我從來沒有面對過。 我編輯了我原來的問題,一切正常,我用Q來管理你的諾言。但就目前而言,你可以閱讀我仍然有一個最終的問題q.all返回一個數組裏面沒有數據...該數據是我應該推到數據庫的最終數據。如果你能解釋這一點,我會很感激。謝謝。 – 2014-12-04 12:26:14

+0

@AyeyeBrazo - 我在'.push()'後面添加了一條必要的return語句。這對於適當返回返回值是必要的。 – jfriend00 2014-12-04 22:06:33

+0

Promise未定義。 – 2014-12-05 13:51:05