wil*_*ler 8 javascript promise angularjs angular-promise
我想用来$q.when()
包装一些非承诺的回调.但是,我无法弄清楚如何在回调中解决承诺.我在匿名函数内部做什么强迫$q.when()
我解释?
promises = $q.when(
notAPromise(
// this resolves the promise, but does not pass the return value vvv
function success(res) { return "Special reason"; },
function failure(res) { return $q.reject('failure'); }
)
);
promises.then(
// I want success == "Special reason" from ^^^
function(success){ console.log("Success: " + success); },
function(failure){ console.log("I can reject easily enough"); }
);
Run Code Online (Sandbox Code Playgroud)
我想复制的功能是这样的:
promises = function(){
var deferred = $q.defer();
notAPromise(
function success(res) { deferred.resolve("Special reason"); },
function failure(res) { deferred.reject('failure'); }
);
return deferred.promise;
};
promises.then(
// success == "Special reason"
function(success){ console.log("Success: " + success); },
function(failure){ console.log("I can reject easily enough"); }
);
Run Code Online (Sandbox Code Playgroud)
这很好,但when()
看起来很好.我只是无法将解析消息传递给then()
.
有更好,更强大的方法来做到这一点.$q
同步抛出异常,正如@Benjamin指出的那样,主要的承诺库正朝着使用完整的Promise代替Deferreds.
这就是说,这个问题是寻找一种方式来做到这一点使用$q
的when()
功能.客观上优越的技术当然是受欢迎的,但不回答这个具体问题.
您基本上是在尝试将现有的回调API转换为承诺.在Angular $q.when
中用于promise聚合,以及用于可能的同化(即,使用另一个promise库).不要害怕,因为你想要的东西是完全可行的,而不是每次都推迟手册.
遗憾的是,对于Angular 1.x,你会遇到过时的延迟界面,这不仅像你说的那样丑陋,而且也是不安全的(它有风险并且同步抛出).
你想要的是所谓的promise构造函数,它是所有实现(Bluebird,Q,When,RSVP,本地承诺等)正在切换到的,因为它更好,更安全.
以下是本机承诺的方法:
var promise = new Promise(function(resolve,reject){
notAPromise(
function success(res) { resolve("Special reason") },
function failure(res) { reject(new Error('failure')); } // Always reject
) // with errors!
);
Run Code Online (Sandbox Code Playgroud)
您$q
当然可以复制此功能:
function resolver(handler){
try {
var d = $q.defer();
handler(function(v){ d.resolve(v); }, function(r){ d.reject(r); });
return d.promise;
} catch (e) {
return $q.reject(e);
// $exceptionHandler call might be useful here, since it's a throw
}
}
Run Code Online (Sandbox Code Playgroud)
哪个会让你这样做:
var promise = resolver(function(resolve,reject){
notAPromise(function success(res){ resolve("Special reason"),
function failure(res){ reject(new Error("failure")); })
});
promise.then(function(){
});
Run Code Online (Sandbox Code Playgroud)
当然,为您的特定情况编写自动promisification方法同样容易.如果您使用回调约定处理大量API,则fn(onSuccess, onError)
可以执行以下操作:
function promisify(fn){
return function promisified(){
var args = Array(arguments.length + 2);
for(var i = 0; i < arguments.length; i++){
args.push(arguments[i]);
}
var d = $q.defer();
args.push(function(r){ d.resolve(r); });
args.push(function(r){ d.reject(r); });
try{
fn.call(this, args); // call with the arguments
} catch (e){ // promise returning functions must NEVER sync throw
return $q.reject(e);
// $exceptionHandler call might be useful here, since it's a throw
}
return d.promise; // return a promise on the API.
};
}
Run Code Online (Sandbox Code Playgroud)
这可以让你做到:
var aPromise = promisify(notAPromise);
var promise = aPromise.then(function(val){
// access res here
return "special reason";
}).catch(function(e){
// access rejection value here
return $q.reject(new Error("failure"));
});
Run Code Online (Sandbox Code Playgroud)
哪个更整洁
归档时间: |
|
查看次数: |
6517 次 |
最近记录: |