2017-12-21 12 views
3

이것이 왜 저에게 효과가 있는지 알 수없는 것 같습니다. 부하중첩 된 비동기/기다리는 노드

module.exports = async function() { 
    try { 
     await load(); 

    } catch (ex) { 
     console.log(ex); 
     logger.error(ex); 
    } 
}; 

async function load() { 
    return await new Promise((resolve, reject) => { 
     TableImport.findAll().then((tables) => { 
      for (let table of tables) { 
       await loadData(table.fileName, table.tableName); 
      } 
      resolve(); 
     }).catch(function (err) { 
      reject(err); 
     }) 
    }) 
}; 


async function loadData(location, tableName) { 
    return await new Promise(function (resolve, reject) { 
     var currentFile = path.resolve(__dirname + '/../fdb/' + location); 

     sequelize.query("LOAD DATA LOCAL INFILE '" + currentFile.replace('/', '//').replace(/\\/g, '\\\\') + "' INTO TABLE " + tableName + " FIELDS TERMINATED BY '|'").then(function() { 
      resolve(tableName); 
     }).catch(function (ex) { 
      reject(); 
     }); 
    }); 
}; 

AWAIT 진술 실패 : 나는 아이로드 프로세스상의 AWAIT을 수행하는 상위 기능을 가지고 ... 차례로 LOAD 프로세스는 다른 그래서 기본적으로 같은 ...라는 LOADDATA을 기다리고 호출

await loadData (table.fileName, table.tableName); SyntaxError : 예기치 않은 식별자

분명히 비동기의 범위에 대해 이해하지 못합니다!

+0

'return await ...'할 이유가 없습니다. 그냥 약속을 되 찾으십시오. 또한, 기존 약속들에 대한 새로운 약속을 포장하는 약속의 안티 패턴을 피해야한다. – jfriend00

답변

3

await은 비동기 기능에서만 사용할 수 있습니다. 당신이 비동기 함수 안에 중첩이 아닌 비동기 기능이있는 경우, 해당 기능에 await를 사용할 수 없습니다

async function load() { 
    return await new Promise((resolve, reject) => { 
     TableImport.findAll().then((tables) => { 
      for (let table of tables) { 
       await loadData(table.fileName, table.tableName); 

위의 .then 방법에 콜백을 가지고있다. 이 콜백은 비동기 적이 아닙니다. async tables => {을 수행하여 문제를 해결할 수 있습니다. load가 비동기이고 findAll이 약속을 반환 이후

그러나 .then를 사용할 필요가 없습니다 :

async function load() { 
    const tables = await TableImport.findAll(); 
    for (let table of tables) { 
     await loadData(table.fileName, table.tableName); 
    } 
} 

내가 loadData가 무엇을 정확히 모르겠어요 당신은 순서대로 테이블을로드 할 수있는 경우 하지만이 병렬화 할 수

const tables = await TableImport.findAll(); 
const loadPromises = tables.map(table => loadData(table.fileName, table.tableName)); 
await Promise.all(loadPromises); 
  • return await 이미 RET 때문에 불필요 약속 urning. 그냥 return가 작동합니다.
  • 내가 제안한대로 다시 작성하면 반환하는 약속 방법이 약속하기 때문에 Promise 개체를 사용할 필요가 없습니다.
  • 원래 기능이 아무 것도 해결하지 못했기 때문에이 기능은 아무 것도 반환하지 않고 동일하게 작동합니다.
  • 원래 기능에서 reject(err) 오류가 발생했습니다. 이 함수는 내부적으로 오류를 처리하지 않으므로 같은 방식으로 오류를 전파합니다.

귀하의 loadData 기능은 다시 작성하고 상당히 단순화 할 수 있습니다

function loadData(location, tableName) { 
    const currentFile = path.resolve(__dirname + '/../fdb/' + location); 
    return sequelize.query("LOAD DATA LOCAL INFILE '" + currentFile.replace('/', '//').replace(/\\/g, '\\\\') + "' INTO TABLE " + tableName + " FIELDS TERMINATED BY '|'"); 
}; 
  • loadData

    await를 사용하지 않기 때문에 비동기 할 필요는 없습니다. 당신은 여전히 ​​약속을 되찾고 있습니다.
  • 원본 코드에서 오류가 반환되지 않았으므로 .catch을 추가 할 수 있습니다. 위의 코드는 .query에 의해 발생한 오류를 반환합니다.
  • 테이블 이름을 전달하면 실제로 반환 값을 사용하지 않으므로 .then을 완전히 삭제했습니다.
+0

좋아요 ... 그 모든 변화를 만들었습니다 ...나는 모든 의견을 이해하지만 한 가지 질문 만한다. 이 작동하지 않음 다음 '비동기 기능 부하를() { 반환 기다리고 있습니다 새로운 약속 ((해결, 거부) => { const를 테이블 =이 TableImport.findAll() 기다리고, 내가 '새로운 약속을 제거 할 때' 을 '작동하는 이유 ... 왜 설명 할 수 있겠습니까? – user3597741

+0

이 문장도 조금 던져 줬습니다 :'비동기 함수가 비동기 함수 안에 중첩되어 있으면 그 함수에서 기다릴 수는 없습니다. LOADDATA를 비동기로 만들었으므로 기다릴 필요가 있습니다. 작동합니다 ... – user3597741

+0

'function loadData {return aPromise;} ... async function load() {await loadData();}' 'async' /'await'의 사용은 범위와 관련이 있습니다. 'loadData'는'load' 함수 범위에 없습니다. 그 범위에서 호출되고 있습니다. –