看完这些示例还不会Promise可以来打我🤧

96 阅读4分钟

Javascript Promise 一经推出就变得非常流行。Javascript Promise 主要用于处理异步任务。在本文中,我们将通过示例深入探讨 Promise。
Promise 状态:
Javascript Promise 只能有一种状态:Rejected或Fullfilled。

处于履行或拒绝状态的承诺称为已解决的承诺。

图片描述

Example#1 resolved状态的 Promise

// Asnc function always return Promsie with resolve or resolve state
async function getMyName(){
  return "Vijendra Rana"
}
//OR
function getMyName(){
   return new Promise((resolve)=>{
     resolve("Vijendra Rana")
})
}
//or
function getMyName(){
 return Promise.resolve("Vijendra Rana")
}

Example#2 rejected状态的 Promise

// Asnc function always return Promsie with resolve or resolve state
async function getMyName(){
//Throw here return Promise with rejected state with reason
  throw Error("Name not found")
}
//OR
function getMyName(){
   return new Promise((_,reject)=>{
     reject(Error("Name not found"))
})
}
//or
function getMyName(){
 return Promise.resolve(Error("Name not found"))
}

//Error - when promise rejected, provide proper reason using Error

Example#3 从resolved的 Promise 中获取响应 - 通过使用 then() 链方法

getMyName().then(res =>{
 console.log("------",res)
})

Example#4 promise rejected后 catch()获取错误信息

getMyName().then(res =>{
 console.log("------",res)
})
.catch(err =>{
//log the reasons
})

Example#5 在 then() 中,我们可以添加rejected和resolved处理方法

//Reject Hanndler

async function getAllNames(id) {
  if (id) {
    return ["a", "b", "c"];
  } else {
    throw new Error("id is undefined");
  }
}

//every Promise has resolve and reject hander

const namePromise = getAllNames(12);
// namePromise
//   .then((res) => {
//     console.log(res);
//   })
//   .catch((err) => {
//     console.warn(err);
//   });

console.log(typeof namePromise);

namePromise.then(
  () => {
    console.log("Resolved");
  },
  () => {
    console.log("Unresolved");
  }
);

Example#6 finally() 不管rejected还是resolved都会执行

//finally to clean up

async function getMovies(id) {
  if (id) {
    return ["1", "2", "3"];
  } else {
    throw new Error("Id req");
  }
}

getMovies(12)
  .then((res) => {
    if (!res) {
      throw Error("Unsuccessful attempt");
    } else {
      console.log("data", res);
    }
  })
  .catch((err) => {
    console.log("error-->", err);
    throw new Error("....");
  })
  .finally(() => {
    console.log("more clean up work");
  });

Example#7 在then主动抛出错误,但是不是被cathch捕获

//Promise to reject

async function getMovies(id) {
  if (id) {
    return ["1", "2"];
  } else {
    return [];
  }
}

getMovies().then((res) => {
  if (res.length === 0) {
    return Promise.reject(new Error("unsuccessful response"));
  }
}).catch((err) =>{
    console.warn('---!!!!',err);
});

Example#8 使用 Promise 构造函数创建 Promise。

//Promise Constructor
// const promise = new Promise((resolve, reject) => {
//   // do some async operation then return promise with resolved state
//   setTimeout(() => {
//     resolve();
//   }, [1000]);
// });

//refactor to sleep
// function sleep(ms) {
//   return new Promise((resolve) => {
//     // do some async operation then return promise with resolved state
//     setTimeout(() => {
//       resolve();
//     }, [ms]);
//   });
// }
//further refactor
function sleep(ms) {
  return new Promise((resolve) => {
    // do some async operation then return promise with resolved state
    setTimeout(resolve, ms);
  });
}
//resolve invoked jsut after constructor called not an asynchronous call so if
function Rejectsleep(ms) {
  return new Promise((resolve) => {
    throw Error("+++++");
    setTimeout(resolve, ms);// This line will not be reachable
  });
}

sleep(1000)
  .then(() => {
    console.log("Resolved");
  })
  .catch((err) => {
    console.log("Rejected from resolved promise");
  });

Rejectsleep(1000)
  .then(() => {
    console.log("Resolved");
  })
  .catch((err) => {
    console.log("Rejected from resolved promise");
  });

Example#9 回调函数使用 Promise

//convert call back to promise

//read file from fs lib, Node api use callback heavily
// import { readFile } from "fs";
const fs = require("fs");
//this is  callback based
// fs.readFile(__filename, "utf-8", (error, contents) => {
//   if (error) {
//     console.error(error);
//   } else {
//     console.log(contents);
//   }
// });

//convert to Promise based app
function readFile(path, encoding) {
  return new Promise((resolve, reject) => {
    fs.readFile(path, encoding, (error, contents) => {
      if (error) {
        reject(error);
      } else {
        resolve(contents);
      }
    });
  });
}

readFile(__filename, "utf8").then(
  (contents) => {
    console.log(contents);
  },
  (error) => {
    console.error(error);
  }
);

Example#10 Promise.race() - 获得最快的结果,当有一个执行完成就不再执行

//Promise.race()

//examplep-1
function resolveAfter(ms, value) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(value);
    }, [ms]);
  });
}

// const pA = resolveAfter(1000, "A");
// const pB = resolveAfter(2000, "B");

// const PResult = Promise.race([pA, pB]);
// PResult.then((val) => {
//   console.log(val);
// });

//Least use of Race  method but in one case
function timeout(ms, promise) {
  let timeoutId;
  const timeoutPromise = new Promise((_, reject) => {
    timeoutId = setTimeout(() => {
      reject(Error(`Operation timed out after ${ms}`));
    }, ms);
  });

  return Promise.race([promise, timeoutPromise]).finally(() => {
    clearTimeout(timeoutId);
  });
}

const promise = resolveAfter(1000, "Promise A");

timeout(5000, promise).then(
  (value) => {
    console.log(value);
  },
  (error) => {
    console.error(error);
  }
);

Example#11 Promise.all() - 当所有 API 并行调用时获取所有 Promise

//Promise.all

async function getMovieTitle(id){
 return "Iron Man"
}

async function getMovieId(dir, actor){
  return 1
}

// getMovieId("Rachel","RJD").then((res) =>{
//     if(res){
//         getMovieTitle(res).then((t) =>{
//             console.log('++++',t);
//         })
//     }

// })

//If both are independent call then call Parallely
const promsies = Promise.all([
    getMovieId("Rachel","RJD"),
    getMovieTitle(1)
])

// console.log('Fullfilled Promsie',promsies);
promsies.then(([id,title]) =>{
    // const id = res[0]
    // const title = res[1]

    console.log('Id',id, 'Title',title);
}).catch(err =>{
    console.log(err);
}).finally(() =>{
    //do some clean up work
})

//in order Promise to  be fullfilled , all promise must be fullfilled

Example#12 如果 Promsie.all() 中的任何一个 Promise 失败,则不会返回一个带有拒绝状态的 Promsie。可以使用 Promsie.allSettled()

//Promsie.allSettled
async function getMovieTitle(id) {
  throw Error("Something Wrong!!");
}

async function getMovieId(dir, actor) {
  return 1;
}

//Promise.allSettled always return settlled  promise
Promise.allSettled([getMovieId("Rachel", "RJD"), getMovieTitle(1)]).then(
  ([id, title]) => {
    if (id.status === "fulfilled") {
      console.log(id.value);
    }
    if (title.status === "fulfilled") {
      console.log(title.value);
    }
  }
);

Example#13 Promise.any()  静态方法将一个 Promise 可迭代对象作为输入,并返回一个 Promise。当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateError 拒绝。

//Promsie.any() to make more resilinet in api down time

var promises = [
  Promise.reject(Error("Fail#1")),
  Promise.reject(Error("Fail#2")),
//   Promise.resolve(2),
];

// Promsie.any return fullfilled promise if any Promise is fullfilled

Promise.any(promises).then(
  (value) => {
    console.log("fullfilled ", value);
  },
  (error) => {
    console.warn(error.errors);
  }
);

Example#14 Async/Await - 我们可以使用 JS 中带有 async/await 关键字的写可读性更好的代码。

//Async/Await

function getMovies() {
  return new Promise((resolve, reject) => {
    resolve(["a", "b", "c"]);
    // reject(Error("Erorr Occured"));
  });
}

function getMovies2() {
  return new Promise((resolve) => {
    resolve(["a1", "b1", "c1"]);
  });
}

async function main() {
  try {
    //it is a sequential api call
    // const movies = await getMovies();
    // const movies2 = await getMovies2();
    //parrallel
    const [movies, movies2] = await Promise.all([
      await getMovies(),
      await getMovies2(),
    ]);
    console.log("+++++", movies, movies2);
  } catch (error) {
    console.log("Some error occured");
  }
}

main();

我希望它能帮助理解和编写 JS 中基于 Promise 的代码。