Sử dụng Jquery.Deferred để thực thi tuần tự những tác vụ bất đồng bộ

Cảnh báo đây là một bài viết kèm quảng cáo… hehehe
Hôm nọ có giới thiệu cho chị HR bên mình cái Chrome Extension của mình viết.
Để chị có thể kết nối với nhiều người mà đỡ mất thời gian.
Sau khi dùng một lúc thì chị có ý kiến là chị muốn kết nối với những người trong khi tìm kiếm
chẳng hạn như tìm kiếm với từ khóa Java.

Đối với các tác vụ như like-all trên Facebook, Google+ , Twitter … thí rất đơn giản
chỉ việc tìm tất cả các nút Like và dùng hàm setTimeout để Like hết

Nhưng đối với trang LinkedIn search, thì nội dung của nó được hiển thị keo kiểu phân trang

Thế là mình phải tìm hiểu một chút.

Căn bản gồm có các tác vụ như sau:

  1. Nhấn vào nút connection - Cầm timout.
  2. Load page kế tiếp và thực hiện bước 1 - Cần timeout

Các hàm hiện thực như sau:

Gửi Connection:

function sendInvitation(element, time) {
  var d = $.Deferred();
  console.log("start send : " + element)
  //element.click();
  setTimeout(function() {
    console.log("Done " + element + " after " + time);
    d.resolve(element);
  }, time);
  return d.promise();
}

Mở trang kế tiếp:

function loadMorePage(pageNumber) {
var d = $.Deferred();
console.log("start load new page " + pageNumber);
if (pageNumber == 2) {
  d.reject(true);
  return d.promise();
}
// btnNextPage.click();
setTimeout(function() {
  console.log("finished load next page "+ pageNumber);
  d.resolve(true);
}, 1000);
return d.promise();

}

Hàm gửi Connection một cách tuần tự:

  function sendAllInvitationOnPage() {
    var invitations = getListInvitation();
    var d = $.Deferred();
    var promise = d.promise();
    $.each(invitations, function(index, value) {
     promise = promise.then(function() {
         return sendInvitation(value, 1000);
  });
   });
   d.resolve();
   return promise;

}

Hàm load trang kế tiếp và gửi connection:

function loadNewPageAndSendInvitation(defered, pageNumber) {
loadMorePage(pageNumber).then(function(resolved) {
sendAllInvitationOnPage().then(function(resolved) {
loadNewPageAndSendInvitation(defered,++pageNumber);
});
}, function(rejected) {
defered.resolve();
});
return defered.promise();
}

Và cuối cùng là hàm start:

function sendAllInvitation () {
  console.log("send All Invitation");
  var d = $.Deferred();
  sendAllInvitationOnPage().then(function(resolved) {
	loadNewPageAndSendInvitation(d,1);
  });
  d.done(function(done){
	console.log("done");
  });
}

Các bạn có thể xem code mẫu của mình ở đây.

Và cài thử extentions Like All của mình nếu thích.

Ai có cách nào hay hơn thì đưa ra để cùng thảo luận nhé.

Bạn nghiên cứu về Promise của ES6 đi. Mọi người đang dần bỏ những implementation không chính quy của Promise và trờ về với native Promise

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?