问题描述
我的函数调用链和async.waterfall使用。它的工作原理就像一个魅力。但我想这样做与jQuery推迟。如何将我的code?
从jQuery的网站的例子是这样的。这两种结果传递给完成
功能:
$。当($阿贾克斯(/page1.php),$。阿贾克斯(/page2.php)).done(功能(A1,A2){
// A1和A2解决的第一页和第二页Ajax请求的参数,分别为。
//每个参数是用以下结构的数组:[数据,状态文本,jqXHR]
VAR数据= A1 [0] + A2 [0]; // A1 [0] =鞭,A2 [0] =它
如果(/鞭/ .TEST(数据)){
警报(我们得到了我们来抓!);
}
});
但我的code是不同的。我需要一个回调传递给了瀑布
的每一步,我有如果
S IN回调。如何用jQuery实现它?这可能吗?
async.waterfall([
功能(CB){
VK.Api.call('users.get',{user_ids:res.session.mid,字段:田},功能(userDataRes){
CB(NULL,userDataRes);
});
},
功能(userDataRes,CB){
如果(userDataRes.response [0]。市){
VK.Api.call('database.getCitiesById',{city_ids:userDataRes.response [0]。城市},功能(cityDataRes){
CB(NULL,userDataRes,{城市:cityDataRes.response [0]。名称});
});
}
其他{
CB(NULL,userDataRes,{});
}
},
功能(userDataRes,cityDataRes,CB){
如果(userDataRes.response [0] .country){
VK.Api.call(database.getCountriesById,{country_ids:userDataRes.response [0] .country},功能(countryDataRes){
CB(NULL,userDataRes,cityDataRes,{国家:countryDataRes.response [0]。名称});
});
}
其他{
CB(NULL,userDataRes,{},{});
}
},
功能(userDataRes,cityDataRes,countryDataRes,CB){
VAR resObj = $ .extend(真{} userDataRes.response [0],cityDataRes,countryDataRes);
CB(NULL,resObj);
},
]
功能(ERR,RES){
的console.log(RES :::,RES);
}
);
UPD 1:
所以,我已经实现了一个解决方案,但预期它不工作。有一个在。然后()
和jQuery递延流异步API函数调用有破损。我不知道如何做一个。然后()
函数作为API的回调。
VAR DFR = $ .Deferred();dfr.then(功能(VAL){ //这是一个异步API函数调用。而其回调返回结果传递到下一个。那么()
//但是jQuery的递延流不遵循此API调用。
//它一起去到下一个。那么忽略此API调用。
//如何使它进入这个API调用,并从一个API的回调返回。
VK.Api.call('users.get',{user_ids:res.session.mid,字段:田},功能(userDataRes){
// CB(NULL,userDataRes);
的console.log(countryDataRes:,userDataRes);
返回userDataRes;
});
})。
然后(功能(userDataRes){
的console.log(countryDataRes:,userDataRes);
如果(userDataRes.response [0]。市){
VK.Api.call('database.getCitiesById',{city_ids:userDataRes.response [0]。城市},功能(cityDataRes){
// CB(NULL,userDataRes,{城市:cityDataRes.response [0]。名称});
返回[userDataRes,{城市:cityDataRes.response [0]。名称}];
});
}
其他{
// CB(NULL,userDataRes,{});
返回[userDataRes,{}];
}
})。
然后(功能(ARES){
如果(ARES [0] .response [0] .country){
VK.Api.call(database.getCountriesById,{country_ids:战神[0] .response [0] .country},功能(countryDataRes){
// CB(NULL,userDataRes,cityDataRes,{国家:countryDataRes.response [0]。名称});
返回[战神[0],战神[1],{国家:countryDataRes.response [0]。名称}];
});
}
其他{
CB(NULL,战神[0],{},{});
}
})。
然后(功能(ARES){
VAR resObj = $ .extend(真{}战神[0] .response [0],战神[1],战神[2]);
的console.log(cityDataRes:战神[1]);
的console.log(countryDataRes:ARES [2]);
CB(NULL,resObj);
返回resObj;
})。
完成(功能(RES){
的console.log(RES :::,RES);
});dfr.resolve();
让我们先从一般规则使用承诺:
Which functions are these in your case? Basically, the complete waterfall, each of the waterfall functions that took a cb
and VK.Api.call
.
Hm, VK.Api.call
doesn't return a promise, and it's a library function so we cannot modify it. Rule 2 comes into play:
In our case, it will look like this:
function callApi(method, data) {
var dfr = $.Deferred();
VK.Api.call(method, data, function(result) {
dfr.resolve(result);
});
// No error callbacks? That's scary!
// If it does offer one, call `dfr.reject(err)` from it
return dfr.promise();
}
Now we have only promises around, and do no more need any deferreds. Third rule comes into play:
That result might as well be a promise not a plain value, .then
can handle these - and will give us back a new promise for the eventual result of executing the "something". So, let's chain some then()
s:
apiCall('users.get', {user_ids: res.session.mid, fields: fields})
.then(function(userDataRes) {
console.log("countryDataRes: ", userDataRes);
if (userDataRes.response[0].city) {
return apiCall('database.getCitiesById', {city_ids: userDataRes.response[0].city})
.then(function(cityDataRes) {
return [userDataRes, {city: cityDataRes.response[0].name}];
});
} else {
return [userDataRes, {}];
}
})
.then(function(aRes) {
if (aRes[0].response[0].country) {
return apiCall("database.getCountriesById", {country_ids: aRes[0].response[0].country})
.then(function(countryDataRes) {
return [aRes[0], aRes[1], {country: countryDataRes.response[0].name}];
});
} else {
return [aRes[0], aRes[1], {}];
}
})
.then(function(aRes) {
var resObj = $.extend(true, {}, aRes[0].response[0], aRes[1], aRes[2]);
console.log("cityDataRes: ", aRes[1]);
console.log("countryDataRes: ", aRes[2]);
return resObj;
})
.done(function(res) {
console.log("res::: ", res);
});
At least, that's what your original waterfall did. Let's polish it up a bit by executing getCitiesById
and getCountriesById
in parallel, and removing all the boilerplate of explicitly creating these aRes
arrays.
function callApi(method, data) {
var dfr = $.Deferred();
VK.Api.call(method, data, function(result) {
dfr.resolve(result.response[0]);
// changed: ^^^^^^^^^^^^
});
// No error callbacks? That's scary!
// If it does offer one, call `dfr.reject(err)` from it
return dfr.promise();
}
apiCall('users.get', {user_ids: res.session.mid, fields: fields})
.then(function(userData) {
if (userData.city)
var cityProm = apiCall('database.getCitiesById', {city_ids: userData.city});
if (userData.country)
var countryProm = apiCall("database.getCountriesById", {country_ids: userData.country});
return $.when(cityProm, countrProm).then(function(city, country) {
var resObj = $.extend(true, {}, userData);
if (city)
resObj.city = city.name;
if (country)
resObj.country = country.name;
return resObj;
});
})
.done(function(res) {
console.log("res::: ", res);
});
这篇关于如何使用jQuery递延的功能,而不是async.waterfall?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!