Código fuente de la propiedad Realize Promises/A+ api con detalles de anotación

Implementación de promesas simples/A+

Blog: webvueblog.github.io/promise/

Dirección del almacén: promesa

Implementación de MiniPromise.js

  • MiniPromise.resolve ()
  • MiniPromesa.rechazar()
  • MiniPromesa.entonces ()
  • MiniPromesa.todos ()
  • MiniPromesa.carrera()
  • MiniPromise.cualquiera ()
  • MiniPromise.allSettled()

Explique las promesas en todo momento, aprenda el contenido relacionado con las promesas y use las promesas de manera competente; comprenda lo que las promesas pueden y no pueden hacer.

Una promesa es un componente que abstrae el procesamiento asincrónico de objetos y varias operaciones sobre ellos. Promise se propuso originalmente en el lenguaje E, que es un lenguaje de programación diseñado en base al procesamiento paralelo/paralelo.

La mayoría de nosotros pensamos en usar funciones de devolución de llamada en el procesamiento asíncrono basado en JavaScript.

Procesamiento asincrónico mediante funciones de devolución de llamada

getAsync("file.txt", function(error, result) {
 // 取得失败时的处理
 if (error) {
  throw error;
 }
 // 取得成功时的处理
});
复制代码

Node.js especifica que un parámetro de la función de devolución de llamada en JavaScript es el objeto de error, que es la forma general de escribir en Node.js.

Cuando Promsie, puede modelar fácilmente el procesamiento asíncrono complejo, escriba:

var promise = getAsyncPromise('file.txt');
promise.then(function(result) {
 // 获取文件内容成功时的处理
}).catch(function(error) {
 // 获取文件内容失败时的处理
});
复制代码

Estándar de promesa ES6

Constructor

Promise es similar a XMLHttpRequest, del constructor Promise para crear un nuevo objeto de promesa como interfaz.

Para crear un objeto de promesa, use new para llamar al constructor de la promesa para crear una instancia.

var promise = new Promise(function(resolve, reject) {
 // 异步处理
 // 处理结束后,调用 resolve 或 reject
});
复制代码

Método de instancia

El objeto de promesa generado por new puede usar el método de instancia de promise.then() para establecer su valor en una función de devolución de llamada invocada cuando se resuelve (éxito)/rechaza (falla).

promise.then(onFulfilled, onRejected)
复制代码
  • resolver (éxito)
    • onFulfilled se llamará
  • Cuando rechazar (fracaso)
    • onRejected será llamado

onFulfilled, onRejected 两个都是可选参数。

promise.then 成功和失败时都可以使用。对于异常进行处理时可以采用 promise.then(undefined, onRejected) 这种方式,只指定 reject 时的回调函数即可。不过这种情况下请使用 promise.catch(onRejected) 是更好的选择。

promise.catch(onRejected)
复制代码

Static Method

像 promise 这样的全局对象还拥有一些静态方法。

包括 Promise.all() 还有 Promise.resolve() 等在内,主要都是一些对 Promise 进行操作的辅助方法。

Promise工作流程

promise工作流程代码:

function asyncFunction() {
 return new Promise(function (resolve, reject) {
  setTimeout(function () {
   resolve('Async Hello world');
  }, 1000);
 });
}
复制代码

new Promise 构造器之后,会返回一个 promise 对象

asyncFunction().then(function(value) {
 console.log(value); // => 'Async Hello world'
}).catch(function (error) {
 console.log(error);
});
复制代码

为promise对象设置 .then 调用返回值时的回调函数。

asyncFunction 这个函数会返回 promise 对象,对于这个 promise 对象,我们调用它的 then 方法来设置 resolve 后的回调函数, catch 方法来设置发生错误时的回调函数。

该promise对象会在setTimeout之后的 1000ms 被 resolve, 这时 then 的调用函数会被调用,并输出 'Async Hello world'。

在这种情况下 catch 的回调函数并不会被执行(因为promise返回了resolve),不过如果运行环境没有提供 setTimeout 函数的话,那么就会产生异常,在 catch 中设置的回调函数就会被执行。

如果不使用catch方法,只使用then方法的话:

只声明 promise.then(onFulfilled, onRejected)

asyncFunction().then(function (value) {
 console.log(value);
},function (error) {
 console.log(error);
});
复制代码

Promise的状态

用 new Promise 实例化的 promise 对象有三种状态:

  • has-resolution: FulFilled
    • resolve(成功)时,此时调用 onFulfilled
  • has-rejection: Rejected
    • reject(失败)时,此时调用 onRejected
  • unresolved: Pending
    • 既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态等

建议使用:Pending,Fulfilled,Rejected 的状态名称进行讲述。

pending -> value -> Fulfilled

pending -> error -> Rejected

状态的改变

promise 对象的状态,从 Pending 转换为 Fulfilled 或 Rejected 之后,这个 promise 对象的状态就不会再发生任何变化。

在 .then 后执行的函数可以肯定地说只会被调用一次。并且 Fulfilled 和 Rejected 这两个中的任一状态都可以表示为 Settled(不变的)。

Settled

resolve(成功) 或 reject(失败)

当 promise 的对象状态发生变化时,用 .then 来定义只会被调用一次的函数。

Promise 代码

创建promise对象的流程:

  1. new Promise(fn) 返回一个 promise 对象
  2. 在 fn 中指定异步等处理
    • 处理结果正常的话,调用 resolve(处理结果值)
    • 处理结果错误的话,调用 reject(Error对象)

用 Promise 来通过异步处理方式来获取 XMLHttpRequest(XHR)的数据:

来创建XHR的promise对象

// 运行示例
var URL = "http://xxx.org/get";
getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(function onRejected(error){
console.error(error);
});

function getURL(URL) {
    return new Promise(function (resolve, reject) {
        var req = new XMLHttpRequest();
        req.open('GET', URL, true);
        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.send();
    });
}
复制代码

为promise对象添加处理方法主要有以下两种

  • promise对象被 resolve 时的处理(onFulfilled)
  • promise对象被 reject 时的处理(onRejected)

此时所谓的 通信成功 , 指的就是在被resolve后, promise对象变为FulFilled状态 。

被resolve后的处理,可以在 .then 方法中传入想要调用的函数。

用 new Promise 方法创建promise对象

用 .then 或 .catch 添加promise对象的处理函数

Promise.resolve

静态方法 Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式。

Promise.resolve(18); 等同于 可以认为是以下代码的语法糖:

new Promise(function(resolve){
    resolve(18);
});
复制代码

方法 Promise.resolve(value); 的返回值也是一个promise对象

Promise.resolve(18).then(function(value){
    console.log(value);
})
复制代码

Promise.resolve 方法另一个作用就是将 thenable 对象转换为promise对象。

Promise.resolve 方法另一个作用就是将 thenable 对象转换为promise对象。

ES6 Promises里提到了Thenable这个概念,简单来说它就是一个非常类似promise的东西。

就像我们有时称具有 .length 方法的非数组对象为Array like一样,thenable指的是一个具有 .then 方法的对象。

这种将thenable对象转换为promise对象的机制要求thenable对象所拥有的 then 方法应该和Promise所拥有的 then 方法具有同样的功能和处理过程,在将thenable对象转换为promise对象的时候,还会巧妙的利用thenable对象原来具有的 then 方法。

到底什么样的对象能算是thenable的呢,最简单的例子就是 jQuery.ajax(),它的返回值就是thenable的。

$.ajax('/json/comment.json');// => 拥有 `.then` 方法的对象
复制代码

这个thenable的对象可以使用 Promise.resolve 来转换为一个promise对象。

将thenable对象转换promise对象

var promise = Promise.resolve($.ajax('/json/comment.json'));
// => promise对象
promise.then(function(value){
    console.log(value);
});
复制代码

Promise.resolve 方法可以认为它的作用就是将传递给它的参数填充(Fulfilled)到promise对象后并返回这个promise对象。

Promise.reject

Promise.reject(error) 是 new Promise() 方法的快捷方式。

比如 Promise.reject(new Error("出错了")) 就是下面代码的语法糖形式。

new Promise(function(resolve,reject){
    reject(new Error("出错了"));
});
复制代码

这段代码的功能是调用该promise对象通过then指定的 onRejected 函数,并将错误(Error)对象传递给这个 onRejected 函数。

Promise.reject(new Error("BOOM!")).catch(function(error){
    console.error(error);
});
复制代码

.then 中指定的方法调用是异步进行的

var promise = new Promise(function (resolve){
    console.log("inner promise"); // 1
    resolve(18);
});

promise.then(function(value){
    console.log(value); // 3
});
console.log("outer promise"); // 2
复制代码
function onReady(fn) {
 var readyState = document.readyState;
 if (readyState === 'interactive' || readySate === 'complete') {
  fn();
 } else {
  window.addEventListener('DOMContentLoaded', fn);
 }
}

onReady(function () {
 console.log('DOM fully loaded and parsed');
});
复制代码

then

promise可以写成方法链的形式

aPromise.then(function taskA(value){
    // task A
}).then(function taskB(vaue){
    // task B
}).catch(function onRejected(error){
    console.log(error);
});
复制代码

promise chain

promise-then-catch-flow.js

function taskA() {
    console.log("Task A");
}

function taskB() {
    console.log("Task B");
}

function onRejected(error) {
    console.log("Catch Error: A or B", error);
}

function finalTask() {
    console.log("Final Task");
}

var promise = Promise.resolve();

promise
.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);
复制代码

1657540047581.png

1657540092016.png

  • then
    • 注册 onFulfilled 时的回调函数
  • catch
    • 注册 onRejected 时的回调函数

promise chain 中如何传递参数

return 返回值

每个方法中 return 的值不仅只局限于字符串或者数值类型,也可以是对象或者promise对象等复杂类型

return的值会由 Promise.resolve(return的返回值); 进行相应的包装处理,因此不管回调函数中会返回一个什么样的值,最终 then 的结果都是返回一个新创建的promise对象

Promise.then 不仅仅是注册一个回调函数那么简单,它还会将回调函数的返回值进行转换,创建并返回一个 promise 对象。

catch

Promise.cath 只是 promise.then(undefined, onRejected); 方法的一个别名而已。这个方法用来注册当promise对象状态变为Rejected时的回调函数。

var promise = Promise.reject(new Error("message"));
promise.catch(function (error) {
    console.error(error);
});
复制代码

解决Promise.catch标识符冲突问题

var promise = Promise.reject(new Error("message"));
promise["catch"](function (error) {
    console.error(error);
});

var promise = Promise.reject(new Error("message"));
promise.then(undefined, function (error) {
    console.error(error);
});
复制代码

每次调用then都会返回一个新创建的promise对象

不管是 then 还是 catch 方法调用,都返回了一个新的promise对象。

var aPromise = new Promise(function (resolve) {
    resolve(100);
});

var thenPromise = aPromise.then(function (value) {
    console.log(value);
});

var catchPromise = thenPromise.catch(function (error) {
    console.error(error);
});

console.log(aPromise !== thenPromise); // => true
console.log(thenPromise !== catchPromise);// => true
复制代码

then 和 catch 都返回了和调用者不同的promise对象。

promise object -> then(promise object)(value -> onFulfilled; error -> onRejected) -> catch(error -> onRejected)

then 的使用方式上的差别

1657542373629.png

1657542448788.png

Promise.all

Promise.all 接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then 方法。

使用一个计时器来计算一下程序执行时间

// `delay`毫秒后执行resolve
function timerPromisefy(delay) {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(delay);
        }, delay);
    });
}

var startDate = Date.now();
// 所有promise变为resolve后程序退出
Promise.all([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
]).then(function (values) {
    console.log(Date.now() - startDate + 'ms');
    // 約128ms
    console.log(values); // [1,32,64,128]
});
复制代码

Promise.race

Promise.race 方法 ,接收一个promise对象数组为参数。

Promise.all 在接收到的所有的对象promise都变为 FulFilled 或者 Rejected 状态之后才会继续进行后面的处理, 与之相对的是 Promise.race 只要有一个promise对象进入FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。

then 与 catch 比较

  1. 使用 promise.then(onFulfilled, onRejected) 的话
    • 在 onFulfilled 中发生异常的话,在 onRejected 中是捕获不到这个异常的。
  2. 在 promise.then(onFulfilled).catch(onRejected) 的情况下
    • then 中产生的异常能在 .catch 中捕获
  3. .then 和 .catch 在本质上是没有区别的
    • 需要分场合使用。

由于 .catch 方法是 .then 的别名,我们使用 .then 也能完成同样的工作。只不过使用 .catch 的话意图更明确,更容易理解

练习

then

  • promise.then(onFulfilled, onRejected);

imagen.png

catch

  • promise.catch(onRejected);

imagen.png

resolve

Promise.resolve(promise);

Promise.resolve(thenable);

Promise.resolve(object);

imagen.png

  • 接收到promise对象参数的时候
    • 返回的还是接收到的promise对象
  • 接收到thenable类型的对象的时候
    • 返回一个新的promise对象,这个对象具有一个 then 方法
  • Cuando los parámetros recibidos son de otro tipo (incluidos JavaScript pares o nulos, etc.)
    • Devuelve un nuevo objeto de promesa con este objeto como valor

rechazar

  • Promesa.rechazar(objeto)

A diferencia de Promise.resolve, esta función devuelve un objeto de promesa completamente nuevo incluso si el argumento recibido por Promise.reject es un objeto de promesa.

todos

  • Promise.all(promiseArray);

Genera y devuelve un nuevo objeto de promesa.

El método solo regresará cuando todos los objetos de promesa en la matriz de promesa pasada como parámetro se hayan resuelto, y la promesa recién creada usará el valor de estas promesas.

Si se rechaza alguna de las promesas en los parámetros, toda la llamada Promise.all finalizará inmediatamente y devolverá un nuevo objeto de promesa que se rechaza.

Dado que cada elemento en la matriz de parámetros está envuelto (envuelto) por Promise.resolve, Paomise.all puede manejar diferentes tipos de objetos de promesa.

la raza

  • Promise.race (matriz promesa)

Genera y devuelve un nuevo objeto de promesa.

Si cualquier objeto de promesa en la matriz de promesa de parámetros se resuelve o rechaza, la función regresará y usará el valor de este objeto de promesa para resolver o rechazar.

participar

Estoy participando en el reclutamiento del programa de firma de creadores de la Comunidad Tecnológica de Nuggets, haga clic en el enlace para registrarse y enviar .

Supongo que te gusta

Origin juejin.im/post/7119187138469429262
Recomendado
Clasificación