ajax省市二级联动硬编码,javascript - 如何避免Javascript / jQuery中的硬编码链式异步函数? - 堆栈内存溢出...

概观

你有几个选择。 您可以使用回调来使用这些函数看起来像这样的代码:

getStuff(function(results) {

getMoreStuff(results, doSomethingWithStuff);

});

或者像这样,使用jQuery的Deferred和Promise对象:

getStuff().then(getMoreStuff).then(doSomethingWithStuff):

使用回调

getStuff和getMoreStuff接受一个参数,这个参数在完成后调用,例如:

function getStuff(callback) {

// ^------------------------------ callback argument

$.ajax({

...

success: function(results) {

// other functions involving results

callback(results);

// ^------------------------------------ use the callback arg

}

});

}

...和getMoreStuff类似。

使用Deferred和Promise

jQuery的ajax功能与其Deferred和Promise功能集成在一起。 您只需将return添加到现有功能即可实现,例如:

function getStuff(callback) {

return $.ajax({

...

});

}

(注意:无需success回调。)

然后这段代码:

getStuff().then(getMoreStuff).then(doSomethingWithStuff);

做这个:

getStuff启动其ajax调用并返回调用创建的Promise 。

当该ajax调用完成并解析promise时,将调用getMoreStuff ,并将ajax调用的结果作为其第一个参数。 它开始了它的 ajax调用。

当getMoreStuff的ajax调用完成时,将调用doSomethingWithStuff并调用该调用的结果( getMoreStuff )。

then使用,而不是done ,以便在每个阶段获得正确的结果是很重要的。 (如果你使用done , getMoreStuff 和 doSomethingWithStuff都会看到getStuff的ajax调用的结果。)

这是使用ajax的完整示例:

function getStuff() {

display("getStuff starting ajax")

return $.ajax({

url: "/echo/json/",

type: "POST",

data: {json: '{"message": "data from first request"}'},

dataType: "json"

});

}

function getMoreStuff(results) {

display("getMoreStuff got " + results.message + ", starting ajax");

return $.ajax({

url: "/echo/json/",

type: "POST",

data: {json: '{"message": "data from second request"}'},

dataType: "json"

});

}

function doSomethingWithStuff(results) {

display("doSomethingWithStuff got " + results.message);

}

getStuff().then(getMoreStuff).then(doSomethingWithStuff);

function display(msg) {

var p = document.createElement('p');

p.innerHTML = String(msg);

document.body.appendChild(p);

}

输出:

getStuff starting ajax

getMoreStuff got data from first request, starting ajax

doSomethingWithStuff got data from second request

你不需要使用ajax来获得这个好处,你可以使用自己的Deferred和Promise对象,这样你就可以编写如下链:

one().then(two).then(three);

...对于您可能有异步完成的任何情况。

这是一个非ajax示例:

function one() {

var d = new $.Deferred();

display("one running");

setTimeout(function() {

display("one resolving");

d.resolve("one");

}, 1000);

return d.promise();

}

function two(arg) {

var d = new $.Deferred();

display("Two: Got '" + arg + "'");

setTimeout(function() {

display("two resolving");

d.resolve("two");

}, 500);

return d.promise();

}

function three(arg) {

var d = new $.Deferred();

display("Three: Got '" + arg + "'");

setTimeout(function() {

display("three resolving");

d.resolve("three");

}, 500);

return d.promise();

}

one().then(two).then(three);

function display(msg) {

var p = document.createElement('p');

p.innerHTML = String(msg);

document.body.appendChild(p);

}

输出:

one running

one resolving

Two: Got 'one'

two resolving

Three: Got 'two'

three resolving

必要时可以组合这两个( ajax示例和非ajax示例)。 例如,如果我们从ajax示例中获取getStuff ,并且我们决定在将数据getMoreStuff给getMoreStuff之前必须对数据进行一些处理,我们就会改变它: Fiddle

function getStuff() {

// Create our own Deferred

var d = new $.Deferred();

display("getStuff starting ajax")

$.ajax({

url: "/echo/json/",

type: "POST",

data: {json: '{"message": "data from first request"}', delay: 1},

dataType: "json",

success: function(data) {

// Modify the data

data.message = "MODIFIED " + data.message;

// Resolve with the modified data

d.resolve(data);

}

});

return d;

}

请注意,我们如何使用它并没有改变:

getStuff().then(getMoreStuff).then(doSomethingWithStuff);

所有改变都在getStuff 。

这是关于整个“承诺”概念的一个伟大的事情(它完全不是jQuery特有的,但jQuery为我们提供了方便的版本),它非常适合解耦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值