前端多线程处理 —— Promise对象

  • 前端多线程处理 —— Promise对象已关闭评论
  • 113 次浏览
  • A+
所属分类:Web前端
摘要

在前端编程中,处理一些简短、快速的操作,在主线程中就可以完成。 但是,在处理一些耗时比较长以至于比较明显的事情,比如读取一个大文件或者发出一个网络请求,就需要子线程来完成,以避免只用单线程时造成页面一时无法响应的事情。

在前端编程中,处理一些简短、快速的操作,在主线程中就可以完成。

但是,在处理一些耗时比较长以至于比较明显的事情,比如读取一个大文件或者发出一个网络请求,就需要子线程来完成,以避免只用单线程时造成页面一时无法响应的事情。

以发送网络请求为例,在以往的JavaScript中,使用多个回调函数来处理请求返回的多个状态,如下面的代码:

var xhr = new XMLHttpRequest();   xhr.onload = function () {                                              // 请求成功时调用     document.getElementById("box1").innerHTML=xhr.responseText; }   xhr.onerror = function () {                                             // 请求失败时调用     document.getElementById("box1").innerHTML="请求出错"; }   xhr.open("GET", "./book1/chapt1.php", true); xhr.send();

 如果该请求因为网络延迟等原因没有回应,页面就会卡在该位置而不会执行下面的代码,造成页面展示不佳的问题。

而使用 Promise 对象就不会有这个问题。如下面的代码:

function ajax(URL) {     return new Promise(function (resolve, reject) {         var xhr = new XMLHttpRequest();          req.onload = function () {             if (req.status === 200) {                      resolve(req.responseText);                 } else {                     reject(new Error(req.statusText));                 }              };         req.onerror = function () {             reject(new Error(req.statusText));         };                  req.open('GET', URL, true);         req.send();      }); }  var URL = "./book1/chapt1.php";   <!--       ajax函数返回的Promise对象函数会在子程序中执行     主程序可以执行接下去的代码     Promise的then函数和catch函数会等待请求的返回结果 --> ajax(URL).then((value) => {                                              document.getElementById("box1") = value;                       // 请求成功 }).catch((error) => {     document.getElementById("box1") = error;                       // 请求失败 });

这样看,Promise虽然解决了问题,但看起来更加复杂了,代码也更多了,但是在接下来的例子中,你会看到Promise使代码更优雅的应用。

例如有这样一个“函数瀑布”实现的功能:

setTimeout(function () {     console.log("First");     setTimeout(function () {         console.log("Second");         setTimeout(function () {             console.log("Third");             setTimeout(function () {                 console.log("Fourth");             }, 2000);         }, 1000);     }, 2000); }, 1000);

 可以想象,在一个复杂的程序中,这样的函数无论是维护还是异常处理都是一件特别繁琐的事情,而且会让缩进格式变得非常冗赘。

 

现在使用Promise来实现就有条理和优雅的多:

function print(delay, message) {     return new Promise(function (resolve, reject) {         setTimeout(function () {             console.log(message);             resolve();         }, delay);     }); }  print(1000, "First").then(function () {     return print(2000, "Second"); }).then(function () {     return print(1000, "Third"); }).then(function () {     print(2000, "fourd"); });