[javascript] JavaScript에서 then () 함수는 무엇을 의미합니까?

나는 다음과 같은 코드를 보았습니다.

myObj.doSome("task").then(function(env) {
    // logic
});

어디 then()에서 왔습니까?



답변

JavaScript에서 비동기 호출을 처리하는 전통적인 방법은 콜백입니다. 응용 프로그램을 설정하기 위해 서버를 차례로 세 번 호출해야한다고 가정 해 봅시다. 콜백을 사용하면 코드가 다음과 같이 보일 수 있습니다 (서버 호출을위한 xhrGET 함수 가정).

// Fetch some server configuration
    xhrGET('/api/server-config', function(config) {
        // Fetch the user information, if he's logged in
        xhrGET('/api/' + config.USER_END_POINT, function(user) {
            // Fetch the items for the user
            xhrGET('/api/' + user.id + '/items', function(items) {
                // Actually display the items here
            });
        });
    });

이 예에서는 먼저 서버 구성을 가져옵니다. 그런 다음이를 바탕으로 현재 사용자에 대한 정보를 가져온 다음 마지막으로 현재 사용자의 항목 목록을 가져옵니다. 각 xhrGET 호출은 서버가 응답 할 때 실행되는 콜백 함수를 사용합니다.

물론 더 많은 수준의 중첩이있을수록 코드를 읽고, 디버깅하고, 유지 관리하고, 업그레이드하고, 기본적으로 작업하기가 더 어렵습니다. 이것을 일반적으로 콜백 지옥이라고합니다. 또한 오류를 처리해야하는 경우 각 xhrGET 호출에 다른 함수를 전달하여 오류 발생시 수행해야 할 작업을 알려야합니다. 일반적인 오류 처리기를 하나만 원한다면 불가능합니다.

Promise API는 이러한 중첩 문제와 오류 처리 문제를 해결하도록 설계되었습니다.

Promise API는 다음을 제안합니다.

  1. 각 비동기 작업은 promise개체 를 반환 합니다.
  2. promise객체 then에는 success
    핸들러와 error핸들러 라는 두 개의 인수를 사용할 수 있는 함수가 있습니다 .
  3. 비동기 작업이 완료된 후 함수 의 성공 또는 오류 처리기가 한 번만then 호출됩니다 .
  4. then함수는 또한 promise여러 호출을 연결하기 위해를 반환 합니다.
  5. 각 핸들러 (성공 또는 오류)는을 리턴 할 수 있으며 value,이 argument체인은 promises 체인에서 으로 다음 함수에 전달됩니다 .
  6. 핸들러가 a를 리턴하면 promise(다른 비동기 요청을 작성), 요청이 완료된 후에 만 ​​다음 핸들러 (성공 또는 오류)가 호출됩니다.

따라서 앞의 예제 코드는 promise와 $httpservice (AngularJs)를 사용하여 다음과 같은 것으로 변환 될 수 있습니다 .

$http.get('/api/server-config').then(
    function(configResponse) {
        return $http.get('/api/' + configResponse.data.USER_END_POINT);
    }
).then(
    function(userResponse) {
        return $http.get('/api/' + userResponse.data.id + '/items');
    }
).then(
    function(itemResponse) {
        // Display items here
    },
    function(error) {
        // Common error handling
    }
);

전파 성공 및 오류

체이닝 약속은 서비스가 서버 호출을하고 데이터를 후 처리 한 다음 처리 된 데이터를 컨트롤러에 반환하는 등 많은 기능을 수행 할 수있는 매우 강력한 기술입니다. 그러나 promise체인으로 작업 할 때
명심해야 할 것이 몇 가지 있습니다.

promiseP1, P2 및 P3의 3 가지 약속이 있는 다음의 가상 체인을 고려하십시오 . 각각 promise에는 성공 처리기와 오류 처리기가 있으므로 P1의 경우 S1 및 E1, P2의 경우 S2 및 E2, P3의 경우 S3 및 E3이 있습니다.

xhrCall()
  .then(S1, E1) //P1
  .then(S2, E2) //P2
  .then(S3, E3) //P3

오류가없는 정상적인 흐름에서는 응용 프로그램이 S1, S2 및 마지막으로 S3을 통과합니다. 그러나 실제 생활에서는 그렇게 매끄럽지 않습니다. P1에 오류가 발생하거나 P2에 오류가 발생하여 E1 또는 E2를 트리거 할 수 있습니다.

다음과 같은 경우를 고려하십시오.

• P1의 서버로부터 성공적으로 응답을 받았지만 반환 된 데이터가 정확하지 않거나 서버에 사용 가능한 데이터가 없습니다 (빈 배열이라고 생각). 이 경우 다음 약속 P2의 경우 오류 처리기 E2를 트리거해야합니다.

• 약속 P2에 대한 오류가 발생하여 E2가 트리거됩니다. 그러나 처리기 내부에는 캐시의 데이터가 있으므로 응용 프로그램이 정상적으로로드 될 수 있습니다. 이 경우 E2 이후에 S3이 호출되도록 할 수 있습니다.

따라서 성공 또는 오류 처리기를 작성할 때마다 호출해야합니다. 현재 기능이 제공되면 약속 체인의 다음 처리기에 대한 성공 또는 실패입니까?

체인의 다음 약속에 대한 성공 처리기를 트리거하려는 경우 성공 또는 오류 처리기에서 값을 반환하면됩니다.

반면에 체인에서 다음 약속에 대해 오류 처리기를 트리거하려는 경우 deferred객체 를 사용하고 해당 reject()메서드를 호출 하여이를 수행 할 수 있습니다

이제 지연된 대상은 무엇입니까?

jQuery의 지연된 객체는 나중에 비동기 적으로 완료되는 작업 단위를 나타냅니다. 작업 단위가 완료되면 deferred오브젝트를 분석하거나 실패하도록 설정할 수 있습니다.

deferred개체는 포함 promise개체를. promise오브젝트를 통해 작업 단위가 완료 될 때 수행 될 작업을 지정할 수 있습니다. promise객체 에 콜백 함수를 설정하면됩니다 .

Jquery에서 지연된 객체 : https://api.jquery.com/jquery.deferred/

AngularJs의 지연된 객체 : https://docs.angularjs.org/api/ng/service/ $ q


답변

then () 함수는 jQuery 또는 AngularJS와 같은 일부 라이브러리 또는 프레임 워크에서 사용되는 “자바 스크립트 약속”과 관련이 있습니다.

약속은 비동기 작업을 처리하기위한 패턴입니다. promise를 사용하면 콜백으로 사용할 함수를 지정할 수있는 “then”이라는 메서드를 호출 할 수 있습니다.

자세한 내용은 다음을 참조 하십시오 : http://wildermuth.com/2013/8/3/JavaScript_Promises

그리고 Angular 약속의 경우 : http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/


답변

내 지식 으로는 (이 글을 쓰는 시점에) 내장 then()방법 이 없습니다 javascript.

그것이 doSome("task")반환 하는 것은 무엇이든 이라는 메소드를 가지고있는 것으로 보입니다 then.

doSome()콘솔에 반환 결과를 기록하면 반환 된 내용의 속성을 볼 수 있어야합니다.

console.log( myObj.doSome("task") ); // Expand the returned object in the
                                     //   console to see its properties.

업데이트 (ECMAScript6 기준) :-

.then()함수는 순수 자바 스크립트에 포함되었습니다.

모질라 문서에서 여기 ,

then () 메서드는 Promise를 반환합니다. Promise의 성공 및 실패 사례에 대한 콜백 함수라는 두 가지 인수가 필요합니다.

Promise 객체는 다음과 같이 정의됩니다.

Promise 개체는 지연 및 비동기 계산에 사용됩니다. 약속은 아직 완료되지 않았지만 향후에 예상되는 작업을 나타냅니다.

즉, Promise아직 계산되지 않은 값의 자리 표시 자 역할을하지만 앞으로는 해결 될 것입니다. 그리고이 .then()함수는 Promise에서 호출 될 함수를 해결할 때 성공 또는 실패로 연결하는 데 사용됩니다.


답변

여기에 내가 일하는 방식을 분명히하기 위해 만든 것이 있습니다. 다른 사람들 도이 구체적인 예를 유용하게 사용할 수 있다고 생각합니다.

doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');

// For pedagogical reasons I originally wrote the following doit()-function so that 
// it was clear that it is a promise. That way wasn't really a normal way to do 
// it though, and therefore Slikts edited my answer. I therefore now want to remind 
// you here that the return value of the following function is a promise, because 
// it is an async function (every async function returns a promise). 
async function doit() {
  log('Calling someTimeConsumingThing');
  await someTimeConsumingThing();
  log('Ready with someTimeConsumingThing');
}

function someTimeConsumingThing() {
  return new Promise(function(resolve,reject) {
    setTimeout(resolve, 2000);
  })
}

function log(txt) {
  document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>


답변

다음은 작은 JS_Fiddle입니다.

그런 다음 약속이 해결 된 후에 사용할 수있는 메소드 콜백 스택입니다 .jQuery와 같은 라이브러리의 일부이지만 이제는 네이티브 JavaScript로 사용할 수 있으며 작동 방법에 대한 자세한 설명은 다음과 같습니다

jQuery에 약속이있는 것처럼 모든 JavaScript를 약속대로 할 수 있습니다. 모든 약속을 쌓은 다음 콜백 확인 및 거부로 호출 할 수 있습니다. 이는 비동기 호출을 연결하는 방법입니다.

배터리 충전 상태에 대한 MSDN Docs에서 분기 및 편집했습니다.

이 작업은 사용자 랩톱 또는 장치가 배터리를 충전하고 있는지 확인하는 것입니다. 그런 다음 호출되고 당신은 당신의 작업 포스트 성공을 할 수 있습니다.

navigator
    .getBattery()
    .then(function(battery) {
       var charging = battery.charging;
       alert(charging);
    })
    .then(function(){alert("YeoMan : SINGH is King !!");});

다른 es6 예

function fetchAsync (url, timeout, onData, onError) {
    
}
let fetchPromised = (url, timeout) => {
    return new Promise((resolve, reject) => {
        fetchAsync(url, timeout, resolve, reject)
    })
}
Promise.all([
    fetchPromised("http://backend/foo.txt", 500),
    fetchPromised("http://backend/bar.txt", 500),
    fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
    let [ foo, bar, baz ] = data
    console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
    console.log(`error: ${err}`)
})

정의 :: 그런 다음 비동기 콜백을 해결하는 데 사용되는 방법입니다

이것은 ES6에 도입되었습니다

적절한 문서를 여기에서 찾으십시오. Es6 Promises


답변

doSome이 myObj 인 this를 반환한다고 생각합니다. 표준 방법 체인 …

doSome이 이것을 반환하지 않으면 doSome이 실행 된 객체이므로 then 메소드를 사용하여 일부 객체를 반환합니다.

@ Patrick이 지적했듯이 표준 js에는 then ()이 없습니다.


답변

doSome ( “task”)는 promise 객체를 반환해야하며 그 promise에는 항상 then 함수가 있습니다. 따라서 코드는 다음과 같습니다

promise.then(function(env) {
    // logic
}); 

그리고 이것은 멤버 함수에 대한 일반적인 호출이라는 것을 알고 있습니다.