本文介绍了如何使用jQuery递延的功能,而不是async.waterfall?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的函数调用链和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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 22:50