2014-09-12 3 views
1

방금 ​​콜백 지옥을 정리하기 위해 약속을 사용하기 시작했습니다.Bluebird Promise Scope

나는 블루 버드를 사용하기로 결정했으며 브라우저에서 실행 중이지만 즉시 범위 지정 문제가 발생했습니다.

새로운 약속으로 thisArg를 설정하는 방법이 있습니까? 아래 예제는 약속 해결 프로그램의 'this'값이 브라우저 창에 설정되어 있지만 주변 변수로 설정하여 멤버 변수에 쉽게 액세스 할 수 있음을 보여줍니다.

.bind() 메소드가 있지만 약속이 아니라 'then()'메소드 만 범위가 있음을 발견했습니다. 나는 또한 약속 앞에서 'var me = this'를 가질 수 있다는 것을 알았지 만 가능하다면 그것을 피하고 싶었다.

function MyObject() { 
    this.value = 7; 
} 

MyObject.prototype.getValue = function() { 
    return new Promise(function (resolve) { 
     // some request/processing that takes a long time 
     var result = Ajax.request(...); 

     resolve({ 
      value: this.value, 
      result: result 
     }); 
     // 'this' is set to window instead of the instance, 
     // resulting in this.value as undefined 
    }); 
} 

var obj = new MyObject(); 
obj.getValue().then(function (value) { 
    console.log(value); // preferably outputs 7 
}) 

답변

2

아니요, 없습니다. 당연히 use the default approaches 일 수 있지만 그렇게 할 필요는 없습니다.

무거운 처리를 수행하고 비동기 적으로 값을 되 찾는 경우 값에 대해 을 약속하고자합니다. 결과 값을 원래 인스턴스의 속성으로 설정할 필요가 없습니다. 당신이 기적 인스턴스에 설정했던 .value을 얻고 싶은 경우

MyObject.prototype.getValue = function() { 
    return new Promise(function(resolve) { 
     // lots of processing to make a `value` 
     resolve(value); // no `this` at all! 
    }); 
}; 

, 당신은 Promise 생성자가 필요하지 않습니다. 그냥 기존의 값에 대한 약속을하기 위해 Promise.resolve를 사용

MyObject.prototype.getValue = function() { 
    // TODO: lots of processing 
    return Promise.resolve(this.value); 
}; 

을 또는 귀하의 경우에도 Promise.method : 그것은 기반의 주요 의견을 같이

// TODO: lots of processing 
MyObject.prototype.getValue = Promise.method(function() { 
    return this.value; 
}); 
+1

을 약속 * 아무것도 *하지만 무엇을 반환해야 자체 내부에서 생성/반입됩니까? 반환 된 결과에 인스턴스에 이미있는 값을 추가하려는 경우 어떻게해야합니까? 나는 단지 안티 패턴을 피하려고 노력하고있다. 내 예에서 Promise.resolve를 사용할 수는 있지만 실제로 this.value를 Ajax 호출 결과와 함께 포함시키고 싶다고 말합니다. –

+0

"Promise.method"가 여기에서하는 것을 강조해야한다고 생각합니다.이 문제를 정확히 해결합니다. 또한, 비동기 계산이 포함되어 있지 않다면'this.value' 약속을 반환 할 필요가 없습니다. –

+0

@BrendanAnnable 콜백 코드를 약속 된 코드로 변환하는 로직을 작성하기 위해 약속 생성자를 사용해야합니다. - 당신은'.bind' 체인을 가지고 있습니다. –

2

이 더 후 주석에 대한 답변입니다 . Ajax.request의 promisifyed 버전이 될 것입니다,이 경우

Ajax.requestAsync : 나는 내 코드에서 다음과 같이 것이 필요로하는 RAR 상황에서

.

다른 곳으로 옮길 수도 있습니다. 이 같은

MyObject.prototype.getValue = function() { 
    return Ajax.requestAsync(...) 
    .bind(this) 
    .then(function(result) { 
     return { 
       value: this.value, 
       result: result 
      } 
    }); 
} 

또는 뭔가 :

MyObject.prototype.getValue = function() { 
    var returnValue = { 
     value: this.value 
    }; 

    return Ajax.requestAsync(...) 
    .then(function(result) { 
     returnValue.result = result; 
     return returnValue; 
    }); 
} 

A는 거의 같은 구조 사용하지 : 그래서 일반적인 규칙을 참조하려고 해요

MyObject.prototype.getValue = function() { 
    return Promise.all([this, Ajax.requestAsync(...)]) 
    .spread(function(object, result) { 
     return { 
     value: object.value, 
     result: result 
     }; 
    }); 
} 
관련 문제