亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在ES6中使用Promise

發布時間:2021-03-20 17:03:34 來源:億速云 閱讀:160 作者:Leah 欄目:web開發

怎么在ES6中使用Promise?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

在javascript中,代碼是單線程執行的,對于一些比較耗時的IO操作,都是通過異步回調函數來實現的。

但是這樣會存在一個問題,當下一個的操作需要上一個操作的結果時,我們只能把代碼嵌到上一個操作的回調函數里,這樣一層嵌一層,最終形成回調地獄。

$.get('/login.php', function (login) {
  $.get('/user.php', function (user) {
    $.get('/info.php', function (info) {
      //代碼就這樣一層嵌一層,不夠直觀,維護也麻煩
    });
  });
});

為了解決這種問題,ES6中就提供了Promise方法來解決這種問題。

Promise是一個構造函數,通過它,我們可以創建一個Promise實例對象。

let p = new Promise(function (resolve, reject) {
  setTimeout(() => {
    console.log('OK');
    resolve('OK');
  }, 1000);
});

Promise構造函數接受一個函數作為參數,這個函數有兩個參數,resolve和reject。

resolve函數是將Promise的狀態設置為fulfilled(完成),reject函數是將Promise的狀態設置為rejected(失敗)。

上述代碼,我們并沒有進行任何調用,當運行時,間隔1秒后輸出了'OK'。所以這里需要注意,我們通常使用Promise時,需要在外層再包裹一層函數。

let p = function () {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      console.log('OK');
      resolve('OK');
    }, 1000);
  });
};
p();

上面的代碼p();返回的是一個Promise實例對象,Promise對象上有 then() , catch() , finally() 方法。

then方法有兩個參數,onFulfilled和onRejected,都是函數。

onFulfilled用于接收resolve方法傳遞過來的數據,onRejected用于接收reject方法傳遞過來的數據。

let p = function () {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.5) {
        resolve('OK');
      } else {
        reject('ERR');
      }
    }, 1000);
  });
};
p().then(function (data) {
  console.log('fulfilled', data);
}, function (err) {
  console.log('rejected', err);
});

then()方法總是會返回一個Promise實例,這樣我們就可以一直調用then()。

在then方法中,你既可以return 一個具體的值 ,還可以return 一個Promise對象。

如果直接return的是一個數據,那then方法會返回一個新Promise對象,并以該數據進行resolve。

let p = function () {
  return new Promise(function (resolve, reject) {
    resolve(1);
  });
};
p().then(function (data) {
  console.log(`第 ${data} 次調用`);
  //注意這里直接返回的值
  //then會創建一個新的Promise對象,并且以返回的值進行resolve
  //那么該值會被下面的then方法的onFulfilled回調拿到
  return ++data;
}).then(function (data) {
  console.log(`第 ${data} 次調用`);
  return ++data;
}).then(function (data) {
  console.log(`第 ${data} 次調用`);
  return ++data;
});

如果返回的是一個Promise對象,請看下面代碼。

let p = function () {
  return new Promise(function (resolve, reject) {
    resolve(1);
  });
};
p().then(function (data) {
  console.log(`第 ${data} 次調用`);
  return new Promise(function (resolve, reject) {
    resolve(++data);
  });
}).then(function (data) {
  console.log(`第 ${data} 次調用`);
  return new Promise(function (resolve, reject) {
    resolve(++data);
  });
}).then(function (data) {
  console.log(`第 ${data} 次調用`);
  return new Promise(function (resolve, reject) {
    resolve(++data);
  });
});

其實效果與直接返回值的是一樣的。

即然then()可以進行鏈式操作,那我們最早之前的回調地獄寫法,就可以通過它進行改進了。

function login() {
  return new Promise(function (resolve, reject) {
    $.get('/login.php', function (result) {
      resolve(result);
    });
  });
}
function user(data) {
  return new Promise(function (resolve, reject) {
    $.get('/user.php', function (result) {
      resolve(result);
    });
  });
}
function info(data) {
  return new Promise(function (resolve, reject) {
    $.get('/info.php', function (result) {
      resolve(result);
    });
  });
}
login().then(function (data) {
  console.log('處理login');
  //把login異步處理獲取的數據,傳入到下一個處理中。
  return user(data);
}).then(function (data) {
  console.log('處理user');
  //把user異步處理獲取的數據,傳入到下一個處理中。
  return info(data);
}).then(function (data) {
  console.log('處理info');
});

這樣修改后,回調地獄層層嵌套的結構就變的清晰多了。上述代碼是偽代碼。

Promise對象還有一個catch方法,用于捕獲錯誤,該方法與 then(null, onRejected) 等同,是一個語法糖。

let p = function () {
  return new Promise(function (resolve, reject) {
    resolve('開始');
  });
};
p().then(function (data) {
  console.log('1');
  return new Promise(function (resolve, reject) {
    reject('錯誤1');
  });
}).then(function (data) {
  console.log('2');
  return new Promise(function (resolve, reject) {
    reject('錯誤2');
  });
}).then(function (data) {
  console.log('3');
  return new Promise(function (resolve, reject) {
    reject('錯誤3');
  });
}).catch(function (reason) {
  console.log(reason);
});

注意,一旦操作中有錯誤發生,則會進入到catch中,后面的操作將不再執行。

Promise對象內部自帶了try catch,當代碼運行時錯誤,會自動以錯誤對象為值reject,并最終被catch捕獲。

let p = function () {
  return new Promise(function (resolve, reject) {
    resolve('開始');
  });
};
p().then(function (data) {
  //注意這里打印了一個未定義的變量
  console.log(a);
}).catch(function (reason) {
  //這里會捕獲到錯誤
  console.log('rejected');
  console.log(reason);
});

Promise還提供了,all(),race(),reject(),resolve()等在構造函數上的方法,調用這些方法并不需要實例化對象。

all()方法,可以讓我們并行的執行異步操作,直到所有操作完成了,才執行回調。

function fn1() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('fn1');
    }, 1000);
  });
}
function fn2() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('fn2');
    }, 2000);
  });
}
function fn3() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('fn3');
    }, 3000);
  });
}
//all會等待所有操作完成,會把所有操作的結果放到一個數組中,傳給then。
Promise.all([fn1(), fn2(), fn3()]).then(function (data) {
  console.log(data);
});

race()方法是誰先處理完,就以誰為準,把最先處理完的結果傳給then。

function fn1() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('fn1');
    }, 1000);
  });
}
function fn2() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('fn2');
    }, 2000);
  });
}
function fn3() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('fn3');
    }, 3000);
  });
}
//race是以誰先處理完,就以誰為準,fn1最先處理完,那fn1的結果會傳給then
//注意這里fn2和fn3還是會執行,不過不會進入then了
Promise.race([fn1(), fn2(), fn3()]).then(function (data) {
  console.log(data);
});

reject()方法,返回一個帶有拒絕原因reason參數的Promise對象。

// Promise.reject('錯誤')
// 等同于
// new Promise(function(resolve, reject) {
//   reject('錯誤');
// });
let p = Promise.reject('錯誤');
p.then(function (data) {
}).catch(function (reason) {
  console.log(reason);
});

resolve()方法,根據傳入的值返回一個Promise對象。

//如果傳入的參數是普通值,則返回一個新Promise對象,并以該值resolve
let p1 = Promise.resolve('OK');
p1.then(function (data) {
  console.log(data);
});
//如果傳入的參數是一個Promise對象,則原封不動的返回該Promise對象
let obj = new Promise(function (resolve, reject) {
  resolve('我是Promise對象');
});
let p2 = Promise.resolve(obj);
p2.then(function (data) {
  console.log(data);
  console.log(p2 === obj);
});
//如果傳入的參數是一個thenable對象(帶有then方法),
//會轉換成Promise對象,并執行thenable對象的then方法
let then = {
  then(resolve, reject) {
    resolve('我是thenable對象');
  }
}
let p3 = Promise.resolve(then);
p3.then(function (data) {
  console.log(data);
});
//如果什么參數都不傳入,則返回狀態為resolved的Promise對象
let p4 = Promise.resolve();
p4.then(function (data) {
  console.log(data);
}).catch(function (reason) {
  console.log(reason);
});

看完上述內容,你們掌握怎么在ES6中使用Promise的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

罗甸县| 凤庆县| 承德市| 荔浦县| 广宁县| 海丰县| 韶山市| 收藏| 邛崃市| 翁牛特旗| 德令哈市| 衡山县| 澳门| 博兴县| 淳化县| 庆安县| 东源县| 类乌齐县| 禄丰县| 沁水县| 建宁县| 临沧市| 仁布县| 泽普县| 台东市| 务川| 宕昌县| 金堂县| 平邑县| 左权县| 罗源县| 东光县| 南郑县| 武宁县| 鹿泉市| 新兴县| 如东县| 昂仁县| 论坛| 鄱阳县| 潼南县|