Promise API, async and await

1. Promise.resolve:把一个value值包装成promise返回

let p=Promise.resolve(2) equals to let p=new Promise((resolve)=>{resolve(2)});
example:

var loadCache;
function loadUrl(url){
  var cache=loadCache.cache || ( loadCache.cache=new Map() );
  if(cache.has(url)) return Promise.resolve( cache.get(url) );
  return fetch(url)
  .then( response=>response.json() )
  .then( text=>{
    cache.set(url,text);
    return text;
  }
}

Promise.resolve保证了这个函数的返回结果在两种情况下都会是 promise对象,保证了接口的统一性。

2. Promise.all: 返回promise对象,输入参数为数组,数组中的元素为promise

let p=Promise.all([...promise...]);
simple example:

Promise.all([
  new Promise(resolve => setTimeout(resolve(1),1000) ),
  new Promise(resolve => setTimeout(resolve(2),2000) ),
])
.then(console.log);
//output: [1,2]

我们来看看Promise.all的一些应用实例

  • example 1: 在这里例子中,Promise.all会等到request数组中的3个promiseresolved之后,然后自己resolve,去执行.then()中的部分。
let urls = [
  'https://api.github.com/users/iliakan',
  'https://api.github.com/users/remy',
  'https://api.github.com/users/jeresig'
];

// 将每个 url 映射到 fetch 的 promise 中
let requests = urls.map(url => fetch(url));

// Promise.all 等待所有作业都被 resolve
Promise.all(requests)
  .then(responses => responses.forEach(
    response => alert(`${response.url}: ${response.status}`)
  ));
  • example 2: 在example 1的基础上,我们进一步利用 promise的链式调用。
let names = ['iliakan', 'remy', 'jeresig'];

let requests = names.map(name => fetch(`https://api.github.com/users/${name}`));

Promise.all(requests)
  .then(responses => {
    // 所有响应都就绪时,我们可以显示 HTTP 状态码
    for(let response of responses) {
      alert(`${response.url}: ${response.status}`); // 每个 url 都显示 200
    }

    return responses;
  })
  // 映射 response 数组到 response.json() 中以读取它们的内容
  .then(responses => Promise.all(responses.map(r => r.json())))
  // 所有 JSON 结果都被解析:“users” 是它们的数组
  .then(users => users.forEach(user => alert(user.name)));

Promise.all其他的一些要点:

  1. 如果传给输入参数数组的不是promise,是一个值,那么Promise.resolve会将其包装成一个resolved promise
  2. 如果其中的一个promisereject状态,Promise.all会等待其他promise的执行结果,但是最后的返回结果是rejected promise

3. Promise.allSettled:对Promise.all的信息补充

简单来说,这个函数是把数组中的每个resolved value包装成一个object, 根据数组中每个返回的promise的状态将其包装成{status: 'fulfilled', value: resolved value} or {status: 'rejected', reason: error}

4. Promise.race:只关心第一个完成的promise, 之后的promise都不会被执行。

5. Promise.reject:与Promise.resolve相似

6. Promisification

Promisification非常有意思,一般回调函数的形式大多为func(para1,para2,...,callback)promisify的过程为:

function(para1,para2,...,paraM){
  return new Promise( (resolve,reject)=>{
    func1(para1,para2,...,paraM, (error, result)=>{
        if(error) reject( new Error('whoops'));
        else resolve(result);
      }
    } 
  );
}
//我们把这一过程继续包装:
function promisify(f){
  return function(...args){
    return new Promise((resolve,reject)=>{
      function callback(error,result){
        if(error) reject(new Error('whoops');
        else resolve(result);
        }
      args.push(callback);
      f.apply(this,...args);
    });
 }
}
//如果callback的参数不止两个
function promisify(f,manyArgs=false){
  return function(...args){
    return new Promise((resolve,reject)=>{
      function callback(error,...result){
        if(error) reject(new Error('whoops');
        else resolve(manyArgs ? result : result[0]);
        }
      args.push(callback);
      f.apply(this,...args);
    });
 }
}

我们在promise中定义回调函数,在其中我们根据error参数的有无来决定promise的状态,然后将回调函数push到函数的arguments中,执行我们想要包装的函数。
这样改写之后,原先放在callback中的操作也会放入.then()函数中,符合promise的正常代码逻辑。

7. async, await

首先我们要记住一条,就是await只能在async函数里面使用,如果在顶层代码中使用会报错。

  • async保证函数的返回值会被包装成一个promise
  • await保证只有当前的promise ready之后才会执行后续的代码,是更优雅地改写promise.then().then()链式调用的语法。
    我们来看一个例子:
async function showAvatar(){
  let response = await fetch('/profiles/user.json');
  let user = await response.json();
  let githubResponse = await fetch(`https://www.github.com/user?${user.name}`);
  let githubUser = await githubResponse.json();
  let img = document.createElement('img');
  img.src=githubUser.avatar_url;
  document.body.append(img);
  await new Promise(resolve=>setTimeout(resolve,3000)); //(*)
  img.remove();
  return githubUser;
}

(*)处的await保证了图片会在页面中保留3s
await handling error:

(async function(){
  let result=await Promise.reject('whoops');
})().catch(console.log);
//'whoops'
//equals to:
(async function(){
      try{
        let result=await Promise.reject('whoops');
      }catch(e){
          console.log(e);
      }
  })();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 12,798评论 1 56
  • 一、Promise的含义 Promise在JavaScript语言中早有实现,ES6将其写进了语言标准,统一了用法...
    Alex灌汤猫阅读 4,276评论 0 2
  • 一. Callback (回调函数) 1.定义:把函数当作变量传到另一个函数里,传进去之后执行甚至返回等待之后的...
    hutn阅读 5,451评论 0 2
  • //本文内容起初摘抄于 阮一峰 作者的译文,用于记录和学习,建议观者移步于原文 概念: 所谓的Promise,...
    曾经过往阅读 5,023评论 0 7
  • 思维导图—让大脑起航 优师优课...
    qdliuyao阅读 1,265评论 0 0

友情链接更多精彩内容