之前介绍过这个作者给的 javascript的语法自测(数组)
现在我们聊一聊异步的事情。
async
首先是最外层的测试,给了一个回调done,然后在两次调用finish()的时候,调用done。
it('you should understand how to use promises to handle asynchronicity', function(done) {
var flag = false;
var finished = 0;
var total = 2;
function finish(_done) {
if (++finished === total) { _done(); }
}
asyncAnswers.async(true).then(function(result) {
flag = result;
expect(flag).to.eql(true);
finish(done);
});
asyncAnswers.async('success').then(function(result) {
flag = result;
expect(flag).to.eql('success');
finish(done);
});
expect(flag).to.eql(false);
});
测试代码比较简单,需要保证then执行的回调函数的输入是async的输入,所以我新返回了一个promise,在支持promise的浏览器里面是可以测试通过的
async: function(value) {
return new Promise(function (resolve) {
resolve(value);
});
},
当然也可以通过语法糖
async: function(value) {
return Promise.resolve(value);
}
作者的答案,利用了Jquery的Deferred
async: function(value) {
var dfd = $.Deferred();
setTimeout(function() {
dfd.resolve(value);
}, 10);
return dfd.promise();
},
manipulateRemoteData
题目要求获得json数据,并进行name的提取和排序
json数据如下
{
"people" : [
{ "name" : "Matt" },
{ "name" : "Rebecca" },
{ "name" : "Paul" },
{ "name" : "Alex" },
{ "name" : "Adam" }
]
}
断言
it('you should be able to retrieve data from the server and return a sorted array of names', function(done) {
var url = '/data/testdata.json';
asyncAnswers.manipulateRemoteData(url).then(function(result) {
expect(result).to.have.length(5);
expect(result.join(' ')).to.eql('Adam Alex Matt Paul Rebecca');
done();
});
});
我用promise写的代码
manipulateRemoteData: function(url) {
return Promise.resolve($.ajax(url)).then(function (value) {
var res = [];
var people = value.people;
for(var i=0;i<people.length;i++){
res.push(people[i].name);
}
return res.sort();
})
}
作者给的代码,用了一下map
manipulateRemoteData: function(url) {
var dfd = $.Deferred();
$.ajax(url).then(function(resp) {
var people = $.map(resp.people, function(person) {
return person.name;
});
dfd.resolve(people.sort());
});
return dfd.promise();
}
};
尝试一些使用 promise写异步
return new Promise(function (resolve,reject) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
resolve(xhr.responseText);
} else {
reject(xhr.status);
}
}
xhr.open("get","url",true);
xhr.send()
}
})