gpt4 book ai didi

javascript - 使用 Angular 的 $q.when() 有理由地解决延迟

转载 作者:数据小太阳 更新时间:2023-10-29 04:12:50 26 4
gpt4 key购买 nike

我想使用 $q.when() 来包装一些非 promise 回调。但是,我无法弄清楚如何从回调中解决 promise 。我在匿名函数中做了什么来强制 $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"); }
);

我想复制的功能是这样的:

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"); }
);

这很好,但是 when() 看起来很不错。我只是无法将解析消息传递给 then()


更新

有更好、更强大的方法可以做到这一点。 $q 同步抛出异常,正如@Benjamin 指出的那样,主要的 promise 库正朝着使用完整 Promises 代替 Deferreds 的方向发展。

就是说,这个问题正在寻找一种使用 $qwhen() 函数来完成此任务的方法。 客观上优越技术当然是受欢迎的,但不要回答这个具体问题。

最佳答案

核心问题

您基本上是在尝试 convert an existing callback API to promises .在 Angular 中,$q.when 用于 promise 聚合和 thenable 同化(即与另一个 promise 库一起工作)。不要害怕,因为您想要的是完全可行的,而无需每次都推迟手动操作。

延迟对象和 promise 构造函数

可悲的是,对于 Angular 1.x,您会被过时的延迟接口(interface)困住,它不仅像您所说的那样丑陋,而且也不安全(它有风险并且会同步抛出)。

您想要的称为 promise 构造函数,它是所有实现(Bluebird、Q、When、RSVP、 native promises 等)都切换到的,因为它更好、更安全。

下面是你的方法在原生 promises 下的样子:

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!
);

当然,您可以在 $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
}
}

哪个会让你做:

var promise = resolver(function(resolve,reject){
notAPromise(function success(res){ resolve("Special reason"),
function failure(res){ reject(new Error("failure")); })
});

promise.then(function(){

});

自动 promise 助手

当然,为您的具体情况编写自动 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.
};
}

这会让你做:

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"));
});

哪个更整洁

关于javascript - 使用 Angular 的 $q.when() 有理由地解决延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18602074/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com