编译器的matchAll踩坑(√) & 正则总结(×)附promise

起因是字符串匹配
给定一个id,和字符串s,找到和s[id]相等,并且距离id最近的下标
那么我们直接matchAll找,按说正常写法是这样的……(仅匹配)
 
 
 
非常坑…… 牛客、赛码平台上都是没有matchAll的。match有
String.prototype.matchAll() is part of the ECMAScript 2020 specification (draft). In TypeScript you can include these library features by adding es2020 or es2020.string, in the compiler options: 
"compilerOptions": {
    "lib": ["es2020.string"]
}
Checking the ts signature for the String and RegExp classes I realized there is no signature for matchAll. One manner to solve it could be:
let matches = str['matchAll'](regexp);

(1) 原始写法
var a='baaa'.matchAll('a');
let all_array_2=[...a];
console.log(all_array_2[0].index);
其实也可可以归结为一句话
var a=[...'baaa'.matchAll('a')][0].index;
(2) 修改后
简单的matchAll后返回一个Object [RegExp String Iterator] {}  这个就解构,用数组就行
需要把matchAll部分修改成 str['matchAll'] (regExp) 实际上就是str.改成了str['']
var matches=[...'baaa'['matchAll']('a')];
console.log(matches);
(3)我们不是‘aaaa’ 这样的字符串,而是变量名怎么做呢
直接重新定义正则 
cmp=‘a’
var e=new RegExp(cmp,"g")
str.matchAll(e)
(4)那么想要快速找到下标,不用这个怎么做呢
match加了g 下标里也没有(实际上传‘a’的话是会隐式的调用正则去转换的)(match只匹配一次会给index,多次就不会了
indexof有限制问题只会匹配一次,但是可以for循环继续往下找。
  • var b = s.indexOf("."); //返回值为1,即第一个字符.的下标位置
  • var e = s.indexOf(".", b + 1); //返回值为11,即第二个字符.的下标位置
(5)重点来看exec:
如果没有设置全局项 /g,该方法将始终返回第一个匹配项:

当全局匹配时,该方法每次返回一个匹配项,直到没有匹配项时返回 null

let reg = /test/g;
let str = '_test_test';

reg.exec(str) // ["test", index: 1, input: "_test_test", groups: undefined]
reg.lastIndex // 5

reg.test(str) // ["test", index: 6, input: "_test_test", groups: undefined]
reg.lastIndex // 10

reg.test(str) // null
reg.lastIndex // 0
简单,直接多弄几次,看返回值就可以了!!!!!
(6)exec、test(测有无)、match(一or多但没信息)、search(只会一次)、replace(替换)
(7)总体来看,好像exec这种比较主流。。
var x = "a.xxx.com b.xxx.com c.xxx.com";
希望得到 ["a","b","c"] 这三个结果
1. 正则需要 添加 g
2.exec 循环,直到返回空
代码如下,会输出 a b c 
var x = "a.xxx.com b.xxx.com c.xxx.com";
var re = /\s?(.*?).xxx.com/g;
while( tempR = re.exec(x)){
  console.log(tempR[1]);
}
参考文档:http://www.w3school.com.cn/jsref/jsref_exec_regexp.asp
exec的功能比 match 强大
提示:请注意,无论 RegExpObject 是否是全局模式,exec() 都会把完整的细节添加到它返回的数组中。这就是 exec() 与 String.match() 的不同之处,后者在全局模式下返回的信息要少得多。因此我们可以这么说,在循环中反复地调用 exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法(其实还有matchall但是这个是后来才出的)。
matchAll必须设置成g,返回值:一个迭代器,可以使用for…of…,数组新增的扩展符(…)或Array.from()实现功能
 
 
 
Promise.all = function(arr){
    return new Promise((resolve,reject)=>{
        let res = []
        let index = 0
        let len = arr.length
        if(len==0){
            resolve(result);
            return;
        }

        for(let i=0;i<len;i++){
            Promise.resolve(arr[i]).then(data=>{
                res[i]=data;
                index++;
                if (index===len) resolve(res);
            }).catch(err=>{
                reject(err)
            })
        }
        /* arr.forEach((p,i)=>{
            p.then(val=>{
                res[i] = val;
                index++;
                if(index===len) resolve(res)
            },err=>{
                reject(err)
            })
        }) */
    })
}

啊?这才是真正的手写promise all?

新增:Promise.all的规范解法还有复盘

promise.all 不能写new,为什么?
emmmm…… 
var p1=new Promise((resolve,reject)=>{
var p1=Promise.resolve('qwq')  ←  这里没有地方写new了呀
我的理解是如果后面加了点号,已经 在调用其方法了就相当于创建了一个新的吧。
规范:都放到all里catch和then就行(MDN)

这个状态问题,我非常不理解???

而且打印出来也一直不对?????????????
这篇不行,我感觉到了

 

promise的内容分为构造函数、实例方法和静态方法

  • 1个构造函数: new Promise
  • 2个实例方法:.then 和 .catch
  • 4个静态方法:Promise.all、Promise.race、Promise.resolve和Promise.reject

啊啊 。一篇综合一旦的文,总体不太行 https://juejin.cn/post/6939688892526231582#heading-30

调用resolvereject并不会终结 Promise 的参数函数的执行。也就是后面有都可以跑,并不是到了resolve就停下来,只是这个resolve的状态就这样了,再reject也不会再更改了——”承诺“ 。(但一般不会这么做~ 或者是return resolve(1) ~
 
Promise.prototype.then() 
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

Promise的缺点

  • 一旦新建,立即执行,无法中途取消
  • Promise内部抛出的错误,无法反映到外部
  • pending状态时无法知道进展到哪一个阶段
then也可以接管rejected
promise.then(function(value) {
  // fulfilled状态的处理
}, function(error) {
  // rejected状态的处理
});
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例),catch也是,因为这俩可以分开去写的。但是,reslove和rejected是不会这么返回的
一般都用const,不知道为什么,为了清楚可以p1=... 
来源:https://es6.ruanyifeng.com/#docs/promise
以及,https://juejin.cn/post/6939688892526231582#heading-30

Promise.resolve返回成功或者失败的Promise对象

let promiseA = Promise.resolve(1);
// 如果传入的参数为非Promise类型的对象,则返回的结果为成功的Promise对象 【那么就是返回这个成功了的promise自己】
let PromiseB = Promise.resolve(new Promise((resolve,reject)=>{
    reject('err');
})
// 如果传入的参数为Promise对象,则参数Promise返回的结果就是 Promise.resolve返回的结果
// 比如这时return 一个[[PromiseResult]]的值为err的Promise对象

Promise.reject返回一个失败的Promise对象

let PromiseA = Promise.reject(new Promise((resolve,reject)=>{
    resolve('err');
})
// 无论传入是啥,就返回一个失败的Promise对象,
[[PromiseResult]]的值为 Promise.reject的参数
🤣🤣reject了就没得救了
是的,没错!但实战中你可能会犯这样的错误:
let p1=Promise.resolve();
let PromiseD= Promise.reject(p1).catch((error)=>{ console.log(error); });
1 有时候浏览器打印的并不是你刚定义的东西
2 没有加catch,它报错了,那我加上吧——结果返回fulfilled。注意catch就像那个then,会fulfilled的。

 

 

或许只能先不去管它吧。

promise的异常穿透

    当使用promise的then进行链式调用时,可以在最后指定失败的回调
    前面的任何错误都会在最后传到失败的回调中去处理
啊啊 其实这也是为什么写了then又可以写catch的原理 而且多个then都适用~

中断promise链

 return new Promise(()=>{});
返回一个状态为pendingpromise对象,就不会走then里的方法了,也就失去了和后面的联系。(因为promise人如其名一旦开始也不太好停止吧

promise.then() 的返回结果(还是struggle是否返回新promise)

  • 如果抛出异常,则返回rejected的Promise对象
  • 如果返回的是非promise类型的任意值,则返回状态为resolved的Promise对象
  • 如果返回的是一个新的promise,则该promise的结果会成为新的promise结果(这也是链式调用的原理:then,catch,all,race等等所有的promise的api的返回值是新的promise对象。
    所以可以继续打点调用promise的方法,以此种方式将任务串联起来)

Promise.all-----------------------------------------------------------------------------额外关照一下----------------------------------------------------------

tips: 返回结果是新的promise,只有所有的Promise对象都成功才成功,只要有一个失败了就直接失败
const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

上面代码中,p1resolvedp2首先会rejected,但是p2有自己的catch方法,该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。

如果p2没有自己的catch方法,就会调用Promise.all()catch方法。

Promise.all()可以确定所有请求都成功了,但是只要有一个请求失败,它就会报错,而不管另外的请求是否结束。
【再去读上面那句话,真的是哦!】

 

 如果加了选中部分,实际上返回的是fulfilled(此时,在firefox打印是pending,但是展开会发现是fulfilled…… console优先极问题吧。在chorme直接打印的~就是~ fulfilled~ 

就,完全可以不加选中的,因为promise.all做了一个承接,,这样也不会报错的。(让all去catch,这里不用写,因为写了then或catch状态就不对了)
最后加了then和catch再去做返回的时候。。
我们已经知道是返回fullfiied了,所以再去写resolve和reject没有用,写了他们也不认识这个。。。可以直接return data,就可以让all拿到了
嗯哈,不是因为已经返回fullfieed。是因为then和catch不认识resovle,以及如果 不报错才返回fulfilled,如果报错是就返回rejected,这是不冲突的(因为不能用resolve,所以可以说是error和return代替了,用es6就直接在then里: .then(res=>res) 就完成了
then(data=>{
   return data;
})这句话了
异常的写法:throw new Error(。。。。)
all在then里接收到的是一个数组,撒个依次排列。

其他2------------------- 

对于race则是,返回结果是新的promise,第一个完成的promise的结果状态就是最终结果的状态。
ES2020 引入了Promise.allSettled()方法,用来确定一组异步操作是否都结束了(不管成功或失败)。所以,它的名字叫做”Settled“,包含了”fulfilled“和”rejected“两种情况。

Promise.any

Promise.any([
  fetch('https://v8.dev/').then(() => 'home'),
  fetch('https://v8.dev/blog').then(() => 'blog'),
  fetch('https://v8.dev/docs').then(() => 'docs')
]).then((first) => {  // 只要有一个 fetch() 请求成功
  console.log(first);
}).catch((error) => { // 所有三个 fetch() 全部请求失败
  console.log(error);
});

只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

Promise.any()Promise.race()方法很像,只有在rejected的时候有一点不同,就是Promise.any()不会因为某个 Promise 变成rejected状态而结束,必须等到所有参数 Promise 变成rejected状态才会结束。

 
 
pending  fulfilled(resolved)
                 rejected  (reject和throw error都可以触~发~)

链接:https://juejin.cn/post/6939688892526231582(其实也算是整理了ryf因为这次确实有点多了而且乱)
 

1、

 
-------------------------------------------------------------------------------------------------------------------------------------------------下面先别看--------------------------------------------------------------------------------------------------------------------------------------------------

2、补promise

Promise可以认为是一种用来解决异步处理的代码规范。常见的异步处理是使用回调函数,回调函数有两种模式,同步的回调和异步的回调。一般回调函数指的是异步的回调
(1)常规写法 Promise((resolve,reject)=>{
    包括后面的then都是双括号的
})
(2)注意如果是 Promise.resolve.then(function(){..
就已经resolve过了,一定要认准这个resolve~
(3)此外,先跟.then 再跟.catch,这样是正常的,写一个promise可以先跟then再跟catch~ 
then 和catch 不冲突,但是和then冲突(两个then就会走跑偏了0.0)
(4)还可以跟.flnally 不管是哪个都会触发
(5)promsie 有三种状态哦
pending  fulfilled(resolved)
                 rejected  (reject和throwerroe都可以)
(6)then 和 catch 只要不报错,返回的都是一个fullfilled状态的promise
这里,,,then和catch是可以并存的,然鹅
 
 
 

await 和async
 
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,react/vue 官方都推荐使用 axios 发 ajax 请求(现在不知道还是不是0.0)
posted @ 2021-08-27 18:42  send/me/a/cat  阅读(564)  评论(0编辑  收藏  举报