2017-09-08 11 views
1

gm을 사용하여 내 nodeJS 응용 프로그램에서 일부 이미지를 조작하고 있습니다. 내 기능이 이렇게 생겼어.NodeJS/gm : 비동기 호출로 약속 함

약간의 조작을위한 스위치가 있습니다 (이 예에서는 회전). gmStream이 생성되고 스위치 .stream()pipe()이 사용됩니다. 지금까지 모든 것이 좋습니다.

스위치 케이스가 resize 인 경우, 이미지 크기를 알아야합니다.이 이미지의 크기는 size()입니다. 그러나 이것은 비동기 호출입니다. 이 gmStream은 스위치 아래에 표시된 stream()에 사용되지 않습니다. 그러나

function manipulate (method, param) { 
    return new Promise(function (resolve, reject) { 

    // Configure GridFS (gridfs-stream) 
    const gfs = Grid(
     MongoInternals.defaultRemoteCollectionDriver().mongo.db, 
     MongoInternals.NpmModule 
    ) 

    switch (method) { 
     case 'rotate': 
     gmStream = gm(readStream) 
      .rotate('#ffffff', param.rotate) 
     break 

     // ... some more cases ... 

     case 'resize': 
     gmStream = gm(readStream) 
      .size(function (err, size) { 
      if (!err && size.width >= 1000 && size.height >= 1000) { 
       gmStream.resize('1000').stream().pipe(writeStream) // <-- should use the stream call below, as there has to be done some DB manipulation... 
      } 
      }) 
     break 
    } 

    // resize case should also use this part... 
    gmStream 
     .stream(function (err, stdout, stderr) { 
     gfs.findOne({ _id: sourceId }, function (err, file) { 
      const writeStream = gfs.createWriteStream({ 
      metadata: { } 
      }) 

      writeStream.on('close', 
      function (newFile) { 
       resolve(newFile) 
      } 
     ) 

      stdout.pipe(writeStream) 
     }) 
     }) 
    }) 
} 

답변

2

당신은 당신이 계신 달성하기 위해 함께 체인 약속 할 수 있습니다 ...이이 stream()에서 좀 더 DB 물건을 완료, 그래서 나는 같은 일을 사용해야합니다. 스위치 케이스의 로직을 Promise가 반환하는 함수로 분리하면 다음과 같이 작동 할 수 있습니다 (면책 조항 : gm을 사용한 적이 없으며 해당 API에 익숙하지 않습니다).

function rotate (readStream, rotate) { 
    return new Promise(function (resolve, reject) { 
    resolve(gm(readStream).rotate('#ffffff', param.rotate)) 
    }) 
} 


function resize (readStream, writeStream) { 
    return new Promise(function (resolve, reject) { 
    var gmStream = gm(readStream) 

    gmStream.size(function (err, size) { 
     if (err) { 
     return reject(err) 
     } 

     if (size.width >= 1000 && size.height >= 1000) { 
     gmStream.resize('1000').stream().pipe(writeStream) 
     resolve(gmStream) 
     } 
    }) 
    }) 
} 


function handleManipulation (args) { 
    return new Promise(function (resolve, reject) { 
    // This will be a Promise for the base gmStream object to work with 
    var gmStream; 

    // Not sure where this comes from, so here's a placeholder 
    var readStream = ...; 

    // You were doing this for every case, so I don't think putting it here 
    // will cause you any grief, but it's a resource to clean up if the 
    // Promise gets rejected, so keep that in mind 
    const writeStream = gfs.createWriteStream({ 
     metadata: { } 
    }) 

    // Figure out which method to create a Promise'd object for 
    switch (args.method) { 
     case 'rotate': 
     gmStream = rotate(readStream, ...) // I'm not sure what the value of 
              // the `rotate` argument should be 
     break 
     case 'resize': 
     gmStream = resize(readStream, writeStream) 
     break 
    } 

    // We wait for the gmStream Promise to resolve before proceeding. 
    gmSteam.then(function (stream) { 
     stream.stream(function (err, stdout, stderr) { 
     if (err) { 
      return reject(err) 
     } 

     gfs.findOne({ _id: sourceId }, function (err, file) { 
      if (err) { 
      return reject(err) 
      } 

      writeStream.on('close', 
      function (newFile) { 
       resolve(newFile) 
      } 
     ) 

      stdout.pipe(writeStream) 
     }) 
     }) 
    }) 
    }) 
}