es6-Promise 72 строки, есть что-нибудь меньше моего?

внешний интерфейс JavaScript

Если все конфессии в мире будут успешными, то таких, как я, не будет в этом мире.

Вечером я вернулась в общежитие и сказала соседкам по комнате, в чем хочу ей признаться. Соседки выступали в роли учителей убеждения и считали, что я ее совсем не достоин. У нее было слишком много качественных выборов. Влюбляясь, я не могу слушать ничьих отговоров.Пока есть шанс 0,1%, я хочу попробовать. Итак, я планировал свою исповедь на следующие несколько дней...
В итоге я дождалась этого дня, погода сегодня была особенно тихая и освежающая, я просила ее пойти ночью на детскую площадку под разными предлогами.Сначала она сопротивлялась, но в конце концов согласилась после того, как меня забили до смерти. Я заранее купил ее любимый молочный чай со вкусом матча, с меньшим количеством сахара. Я до сих пор помню это чувство ожидания, возбуждения, нервозности и полного ожиданий. Через некоторое время она тоже спустилась, и мы шли бок о бок, как на детской площадке. Я представлял себе эту сцену бесчисленное количество дней и ночей.
Сначала я просто болтал с ней о своей недавней жизни.Я слишком нервничал.Это первый раз в жизни, когда я приглашаю девушку на свидание, и это также моя первая исповедь.Я не смог найти подходящую время от темы.Исповедь,она обошла площадку 2 круга,и тоже хотела вернуться.Я вдруг сменила тему и сказала,что в последнее время тебе многие исповедовались.Нет ничего,что тебе нравится? Она сказала, что еще не была тронута, и вдруг насторожилась и сказала: «Если ты признаешься мне, я никогда не думала влюбляться в кого-то из моего класса». Я быстро ответил с краснеющим лицом: Нет, я знаю тебя совсем недавно, я просто думаю, что ты очень хороший, я просто хочу с тобой подружиться... В то время я был расколот, железный и железный. ...
Вернувшись в общежитие, я сделал вид, что ничего не произошло, и сказал им, что мое признание откладывается, и я должен быть полностью готов. Среди ночи я плакала, но не было ни звука, но мне было очень не по себе, и даже мне было немного необъяснимо.
Первое признание было таким гнилым в моем сердце, как и неотправленное письмо.

                              ........
      если я люблю тебя Лин Сяохуа, который так и не научился лазать Покажите себя своими высокими ветвями
      если я люблю тебя Никогда не учите увлеченных птиц повторяя монотонные песни для тени
                              ........

Использование промиса и почерк промиса

Введение и основы использования промисов

Обещание - это владениеthenобъект метода или функция, поведение которой соответствует этой спецификации;
Я не буду подробно представлять спецификацию promise A+, если вам интересно, вы можете перейти на официальный сайт promise, чтобы узнать больше.

thenМетод принимает два параметраonFulfilled, onRejected. Первый является успешным обратным вызовом, а второй — неудачным обратным вызовом. Если реализация в Promise решает ввестиonFulfilled, выполнить отказ, чтобы войтиonRejected.

Люди мало говорят и сразу переходят к галантерее.

       new Promise((reslove, reject) => {
            console.log(1111);
            setTimeout(() => {
                console.log('setTimeut', 2222);
                reslove(1);
            }, 1000);
        }).then(
            (res) => {
                console.log(3333);
            },
            (err) => console.log(err),
        );

Результат выполнения приведенного выше кода выглядит следующим образом:

image.png

Promise.all

Сценарий использования: запрашивайте несколько интерфейсов одновременно, и вам нужно получить информацию внутри одновременно.

Затем используйте обещание в сочетании с setTimeout для имитации аксиом.

        var promise1 = Promise.resolve('我');
        var promise2 = new Promise(function(resolve, reject) {
            setTimeout(resolve, 1000, '不是');
          });
        var promise3 = new Promise(function(resolve, reject) {
          setTimeout(resolve, 2000, '舔狗');
        });
        Promise.all([promise1, promise2, promise3]).then(function(values) {
          console.log(values);
        }); 

На следующем рисунке показан результат печати значений

image.png

Обещание.все минусы

Но у Promise.all есть недостатки.Если запрашивать 5 интерфейсов одновременно, пока один запрос интерфейса не пройден, он уйдет в ловушку

        var promise1 = Promise.resolve('我');
        var promise2 = new Promise(function (resolve, reject) {
            setTimeout(reject, 1000, '不是');
        });
        var promise3 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 2000, '舔狗');
        });
        Promise.all([promise1, promise2, promise3])
            .then(function (values) {
                console.log(values);
            })
            .catch((err) => console.log(err));

Выше я заменил promise2 на reject, он пошёл ловить, на картинке ниже напечатан err

image.png

Promise.allSettled из es11 устраняет недостатки Promise.all
        var promise1 = Promise.resolve('我');
        var promise2 = new Promise(function (resolve, reject) {
            setTimeout(reject, 1000, '不是');
        });
        var promise3 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 2000, '舔狗');
        });
        Promise.allSettled([promise1, promise2, promise3])
            .then(function (values) {
                console.log(values);
            })
            .catch((err) => console.log(err));

Если есть неудачный запрос, он войдет в него и обернет результат объектом.На следующем рисунке показаны напечатанные значения.

image.png

Promise.race

Среди множества запросов тот, который выполняется первым, вернет результат запроса, а медленный будет проигнорирован.

        var promise2 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 1000, '班花');
        });
        var promise3 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 2000, '舔狗');
        });
        Promise.race([ promise2, promise3])
            .then(function (values) {
                console.log(values);
            })

Результат печати значений выглядит следующим образом

image.png

Проникновение значения обещания и как прервать запрос цепочки обещаний

проникать

     Promise.resolve(1)
            .then(2) // 注意这里
            .then(Promise.resolve(3))
            .then(console.log);   // 输出1   这一步等同 .then((res)=>{console.log(res)})

вернуть значение изменяет значение в следующем затем

    Promise.resolve(1)
          .then(function(){return 2})
          .then(Promise.resolve(3))
          .then(console.log)  // 输出2
    Promise.resolve(1)
          .then(function(){return 2})
          .then(function(){return Promise.resolve(3)})
          .then(console.log)  // 输出3

Как прервать обещание
Есть только один способ прервать промис — изменить его состояние на ожидание.
Обещания имеют три состоянияpending,fulfilled, илиrejected

const promise = new Promise((resolve, reject) => {
        resolve(111);
    }).then((res)=>{
        console.log(res)  //打印111
        return  2222
    }).then(res=>{
        console.log(res)  //打印222
        return new Promise(()=>{})
    }).then(res=>{
        console.log(3333)  //不会打印,被中断了
    })
Рукописное обещание

На следующем рисунке показан наш общий бизнес-сценарий, от мелкого к глубокому, сначала мы просто реализуем следующий пример.

    new Promise((resolve,reject)=>{
            setTimeout(()=>{
                console.log(1)
                resolve(2)
            },1000)
        }).then(res=>{
            console.log(res)
        })

Разве это не просто,x instanceof myPromise ? x.then(resolve, reject) : resolve(x);Вам нужно внимательнее посмотреть на эту строку.Если вы застряли в setTimeout, вы можете посмотреть на механизм цикла событий.Если вы не понимаете class, вы можете прочитать мою первую статью.

// 
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

 class myPromise {
            constructor(executor) {
                let self = this;
                self.status = PENDING;
                self.value = undefined;
                self.reason = undefined;
                self.onResolvedCallbacks = [];
                self.onRejectedCallbacks = [];

                let resolve = (value) => {
                    if (self.status === PENDING) {
                        self.status = FULFILLED;
                        self.value = value;
                        self.onResolvedCallbacks.forEach((fn) => fn());
                    }
                };
                
                executor(resolve);
            }
        
            then(onFulfilled, onRejected) {
                let self=this
                 return new myPromise((resolve, reject) => {
                     if (self.status === 'pending') {
                        self.onResolvedCallbacks.push(() => {
                                let x = onFulfilled(self.value);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                        });
                        self.onRejectedCallbacks.push(() => {
                                let x = onRejected(self.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                        });
                      }
                  });
            }
        }

На картинке ниже я добавил reject, а также улучшил биты статуса выполнено и отклонено в методе then. Количество кода не так уж и много...

    const PENDING = 'pending';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'rejected';
     class myPromise {
            constructor(executor) {
                let self = this;
                self.status = PENDING;
                self.value = undefined;
                self.reason = undefined;
                self.onResolvedCallbacks = [];
                self.onRejectedCallbacks = [];

                let resolve = (value) => {
                    if (self.status === PENDING) {
                        self.status = FULFILLED;
                        self.value = value;
                        self.onResolvedCallbacks.forEach((fn) => fn());
                    }
                };

                let reject = (reason) => {
                    if (self.status === PENDING) {
                        self.status = REJECTED;
                        self.reason = reason;
                        self.onRejectedCallbacks.forEach((fn) => fn());
                    }
                };
                try {
                    executor(resolve, reject);
                } catch {
                    reject(err);
                }
            }

            then(onFulfilled, onRejected) {
                //处理then里面不是回调函数情况
                //Promise/A+ 2.2.1 / Promise/A+ 2.2.5 / Promise/A+ 2.2.7.3 / Promise/A+ 2.2.7.4
                onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (v) => v;
                onRejected =
                    typeof onRejected === 'function'
                        ? onRejected
                        : (err) => {
                              throw err;
                          };
                let self = this;
                return new myPromise((resolve, reject) => {
                    if (self.status === 'fulfilled') {
                        setTimeout(() => {
                            try {
                                let x = onFulfilled(self.value);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            } catch (err) {
                                reject(err);
                            }
                        }, 0);
                    }
                    if (self.status === 'rejected') {
                        setTimeout(() => {
                            try {
                                let x = onRejected(self.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            } catch (err) {
                                reject(err);
                            }
                        }, 0);
                    }
                    if (self.status === 'pending') {
                        self.onResolvedCallbacks.push(() => {
                            setTimeout(() => {
                                let x = onFulfilled(self.value);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            }, 0);
                        });
                        self.onRejectedCallbacks.push(() => {
                            setTimeout(() => {
                                let x = onRejected(self.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            }, 0);
                        });
                    }
                });
            }
        }

тщательно проанализируй этоonFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (v) => v;иlet x = onFulfilled(self.value);, вы поймете, почему на картинке ниже такой результат

image.png

Promise.resolve

слишком просто

    static resolve(data){ 
        return new Promise((resolve,reject)=>{ resolve(data); }) 
    }
Promise.all

promise.race писать не буду, можете сослаться на все и подумать как реализовать

    static all(values) {
            if (!Array.isArray(values)) {
              return new TypeError("请输入一个数组")
            }
            return new Promise((resolve, reject) => {
              let resultArr = [];
              let len = 0;
              const dealFn = (value, index) => {
                resultArr[index] = value;
                if (++len === values.length) {
                    resolve(resultArr)
                }
              }
              for (let i = 0; i < values.length; i++) {
                let value = values[i];
                //判断value是否还是个promise
                if (value && typeof value.then === 'function') {
                  value.then((value) => {
                    dealFn(value, i);
                  }, reject);
                } else {
                    dealFn(value, i);
                }
              }
            });
          }
Суммировать

Я использую setTimeout для симуляции его отложенного выполнения, не слишком заботясь об общей отказоустойчивости промисов.Реальный исходный код использует много обратных вызовов для решения проблем с асинхронным выполнением.Я просто реализовал идею обратного вызова в Promise. Если вы хотите узнать больше о Promise, вы можете перейти на официальный сайт, я потерял сознание в нем. Пока вы внимательно читаете приведенный выше контент, по крайней мере, вы не будете беспокоиться о том, что интервьюер попросит вас дать обещание.

Если вам нравится мой рассказ, если вы читаете его впервые, то можете прочитать мою предыдущую статьюnuggets.capable/post/702429…

Наконец, пожалуйста, поддержите железного человека после прочтения!