现在我在核心文件中使用promise.deferred。这允许我在中心位置解决承诺。我一直在读我可能正在使用反模式,我想知道它为什么不好。
所以在我的 core.js 文件中我有这样的函数:
var getMyLocation = function(location) {
var promiseResolver = Promise.defer();
$.get('some/rest/api/' + location)
.then(function(reponse) {
promiseResolver.resolve(response);
)}
.catch(function(error) {
promiseResolver.reject(error);
});
return promiseResolver.promise;
}
然后在我的 getLocation.js 文件中,我有以下内容:
var core = require('core');
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something with data
}).catch(throw error);
在阅读了Bluebird文档和许多关于延迟反模式的博客文章后,我想知道这种模式是否切实可行。我可以将其更改为以下内容:
core.js
var getMyLocation = function(location) {
var jqXHR = $.get('some/rest/api/' + location);
return Promise.resolve(jqXHR)
.catch(TimeoutError, CancellationError, function(e) {
jqXHR.abort();
// Don't swallow it
throw e;
});
getLocation.js
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something
})
.catch(function(error) {
throw new Error();
});
我想我对使用jquery为调用处理xhr请求的中央库的最佳方法感到困惑,但Bluebird是为了承诺。
答案 0 :(得分:19)
你可以在一个jQuery上调用Promise.resolve
,然后让Bluebird吸收它:
var res = Promise.resolve($.get(...)); // res is a bluebird Promise
你也可以直接在Bluebird链中返回jQuery promises并让它同化它。
myBluebirdApi().then(function(){
return $.get(...);
}).then(function(result){
// The jQuery thenable was assimilated
});
下面的代码很接近,但您不需要捕获TimeoutError
,因为jQuery ajax不会抛出这些代码。至于捕捉取消错误。无论如何,如果您希望取消请求,这是最佳做法。
答案 1 :(得分:3)
要将thenable转换为Bluebird承诺,您可以使用这样调用Promise.resolve
:
-module(simple_server).
-export([start/0]).
keep_alive() ->
receive
Any -> io:format("Listening socket: ~p~n",[Any])
end.
start() ->
ssl:start(),
spawn(fun() ->
start_parallel_server(3333),
keep_alive()
end).
start_parallel_server(Port) ->
case ssl:listen(Port, [
binary,
{packet, 0},
{reuseaddr, true},
{active, true},
{certfile,"../etc/server/cert.pem"},
{keyfile,"../etc/server/key.pem"},
{cacertfile,"../etc/server/cacerts.pem"},
{verify,verify_peer},
{fail_if_no_peer_cert,true}
]) of
{ok,Listen} ->
spawn(fun() -> par_connect(Listen) end);
{error,Reason} ->
io:format("error ~p~n",[Reason])
end.
par_connect(Listen) ->
case ssl:transport_accept(Listen) of
{ok,Socket} ->
spawn(fun() -> par_connect(Listen) end),
ssl:ssl_accept(Socket),
print_cert(Socket),
get_request(Socket,[]);
{error,Reason} ->
io:format("Listening stopped (~p)~n",[Reason])
end.
print_cert(Socket) ->
case ssl:peercert(Socket) of
{ok,Cert} ->
io:format("Certificate: ~p~n",[Cert]);
{error,Reason} ->
io:format("Certificate error ~p~n",[Reason])
end.
get_request(Socket,L) ->
receive
{ssl, Socket, Bin} ->
io:format("Server received: ~p~n",[Bin]),
get_request(Socket,L);
{ssl_closed, Socket} ->
io:format("Socket did disconnect~n");
Reason ->
io:format("Client error: ~p~n",[Reason])
end.
大多数JQuery AJAX函数都是可以使用的,但是为了您的信息,如果要将需要回调的函数转换为promise,可以使用Promise.fromNode
。将使用参数var promise = Promise.resolve($.getJSON(...));
调用回调,这在Node.js世界中是惯例:
err, result
如果回调没有预料到第一个参数的潜在错误,你可以解决这个问题:
var promise = Promise.fromNode(function (callback) { request(url, callback); });