2017-09-18 3 views
1

나는 최근에 자바 스크립트 약속을 발견했다. 광고 된 이익은 체인을 연결 한 다음 절을 사용하여 깨끗하게 중첩됩니다.하나의 약속 완료, 긴 목록에서 다음 시작하기 전에

내 코드는 예상대로 작동하지만 콜백을 사용할 때처럼 못생긴 크기로 성장합니다. 이 중첩을 제거하기 위해 체인 연결을 사용하는 더 좋은 방법이 있습니까? 참고 작업 n + 1의 작업을 시작하기 전에 완료하려면 작업 n이 필요합니다.

I 실제 코드는 물건의 어레이를 순차적으로 처리하는 수신

P1().then(() => { 
    return P2() 
}).then(() => { 
    return P3() 
}).catch(() => { console.log("yikes something failed")}) 

했어야 피드백에 기초하여, 매우 간단한 예 고정

'use strict'; 

function P1() { 

    return new Promise((resolve) => { 
     console.log("starting 1") 

     setTimeout(() => { 
      console.log("done 1") 
      resolve(); 
     }, 100) 
    }) 
} 

function P2() { 

    return new Promise((resolve) => { 
     console.log("must start 2 only after 1 is done") 

     setTimeout(() => { 
      console.log("done 2") 
      resolve(); 
     }, 50) 
    }) 
} 

function P3() { 

    return new Promise((resolve) => { 
     console.log("must start 3 only after 3 is done") 

     setTimeout(() => { 
      console.log("done 3") 
      resolve(); 
     }, 10) 
    }) 
} 

console.log("this works, but if list was long, nesting would be terribly deep"); 
// start 1, done 1, start 2, done 2, start 3, done 3. 
P1().then(() => { 
    P2().then(() => { 
     P3() 
    }) 
}) 

. 위의 제안 된 형식은 일련의 단계가 코드로 지정된 경우에만 적합합니다. Promise.do_these_sequentialy와 같이 약속 코드를 명시 적으로 구성하는 코드가 아닌 것 같습니다. 다음과 같이 :

'use strict'; 


function driver(single_command) { 
    console.log("executing " + single_command); 

    // various amounts of time to complete command 
    return new Promise((resolve) => { 
     setTimeout(() => { 
      console.log("completed " + single_command); 
      resolve() 
     }, Math.random()*1000) 
    }) 
} 

function execute_series_of_commands_sequentialy(commands) { 
    var P = driver(commands.shift()); 

    if (commands.length > 0) { 
     return P.then(() => { return execute_series_of_commands_sequentialy(commands) }) 
    } else { 
     return P 
    } 
} 

execute_series_of_commands_sequentialy([1, 2, 3, 4, 5, 6, 7, 8, 9]).then(() => { 
    console.log("test all done") 
}) 

답변

1

약속이 작동하는 방식을 잘못 이해했습니다. 반환 값과 Promise 인스턴스를 연결하여 체인을 따라 더 멀리 전달할 수 있습니다.

P1() 
.then(() => P2()) 
.then(() => P3()) 

중첩 할 필요가 없습니다.

0

async/await을 보면 약속 작성이 크게 단순 해집니다.

JavaScript’s Async/Await Blows Promises Away

기본적으로, 동기화 코드와 같은 비동기 기능을 서면으로 구성되어

async function P(number) { 
 
    return new Promise((resolve) => { 
 
     console.log("starting "+number) 
 

 
     setTimeout(() => { 
 
      console.log("done "+number) 
 
      resolve(); 
 
     }, 800) 
 
    }) 
 
} 
 

 
/* Or the ES6 version : 
 
    const P = async (number) => new Promise((resolve) => { ... }) 
 
*/ 
 

 
async function run(){ 
 
    await P(1) 
 
    await P(2) 
 
    await P(3) 
 
    
 
    console.log("All done!") 
 
} 
 

 
run()

1

가 개인적으로 나는이 형식이 어떻게 보이고 싶은 것은 내가 무엇을 사용

foo(){ 
    P1().then(()=>{ 
    return P2(); 
    }).then(()=>{ 
    return P3(); 
    }).catch((err)=>{ 
    //handle errors 
    }); 
} 
관련 문제