关于 Promise的基本用法,你知道哪些?快来一起学习吧。下面小编就和大家分享,来欣赏一下吧。
Promise的基本用法
Promise是一个类,可以创建一个实例, Promise,也是一个对象,用来传递异步操作的消息。
Promise有三个状态:
penging(对象的初始状态,等到任务的完成或者被拒绝)
fulfilled (任务执行完成并且成功的状态)
rejuce(任务执行完成并且失败的状态)
Promise对象有以下两个特点:
1)对象的状态不受外界影响。
2) 一旦状态改变,就不会再变, Promise的状态只可能从“pending”状态转到“fulfilled”状态或者“pejected”状态,而且不能逆向转换.
缺点:
1)无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
2)如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
Promise的用法
Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,
分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。
var promise = new Promise(function(resolve, reject) {
if (/.异步操作成功 .){
resolve(value);
} else {
reject(error);
}
});
//then里面的函数就跟我们平时的回调函数,不管上面的是什么结果,都会走then里面。
promise .then(function (value){
console.log('成功',value);
},function(reason){
console.log('失败',reason);
})
Promise还提供了all,race、reject、resolve等方法
promise链式调用:会将前一个then的返回值(return)作为下一次成功的回调函数的参数。
promise.all方法:可以传入多个promise ,全部执行后将结果以数组的方式返回,如果有一个失败了,就失败了
promise.race方法:就是赛跑的意思。race的用法与all一样,谁的时间快就实行哪个函数
下面就是的小例子(字符串的倒叙),来讲解promise.all方法和promise.race方法
let p1 =new Promise(function (resolve,reject) {
let str1 ='123456789'; //定义一个字符串
let leg = str1.length; //获取字符串的长度
let re =''; //存储返回值
let i =1; //初始循环变量
let a = setInterval(function () { //定义一个定时器
re+= str1.charAt(leg-i); //获取字符串指定的位置的字符
i++;
if(i > leg) { //判断循环变量大于指定字符串长度
clearInterval(a); //结束定时器
if (i == leg +1) { //判断循环变量 刚好大于指定字符长度时 返回 倒叙字符串
resolve(re);
}else {
reject('倒叙失败!');
}
}
},100);
});
let p2 =new Promise(function (resolve,reject) {
let str1 ='abcdefghijklmn';//定义一个字符串
let leg = str1.length;//获取字符串的长度
let re ='';//存储返回值
let i =1;//初始循环变量
let a1 = setInterval(function () {//定义一个定时器
re+= str1.charAt(leg-i);//获取字符串指定的位置的字符
i++;
if(i > leg){//判断循环变量大于指定字符串长度
clearInterval(a1);//结束定时器
if(i == leg+1){//判断循环变量 刚好大于指定字符长度时 返回 倒叙字符串
resolve(re);
}else {
reject('倒叙失败2!');
}
}
},100);
});
Promise.all([p1,p2]).then(function (value) {
console.log(value);/
},function(reason){
console.log(reason);
})
Promise.race([p1,p2]).then(function (value) {
console.log(value);
},function(reason){
console.log(reason);
})
Promise.resolve方法返回的是一个成功态的Promise实例
Promise.reject方法返回的是一个失败态的Promise实例
以上就是Promise的基本用法
Provide 的用法你知道多少?
第一种用法:
Provide后面接间接宾语 时,通常用with 。
Provide sb. with sth. 为某人提供所需要的东西。”
例子:
下面是美国第一夫人米歇尔 奥巴马所写的一个实例。
Room to Read provides girls with scholarships that cover the cost of housing , food,and books.
“阅读空间(Room to Read)为少女们提供的奖学金,涵盖了食宿费和书费。”
在句子中,girls 是间接宾语,scholarship是直接宾语。
第二种用法:
Provide for
(1) 让某人获取自己所需要的东西。”
谈及父母为家人提供东西时,经常会用到这个表达。
例子:
She says changes such as migration away from rural areas are allowing more women to find work and provide for their families.
诸如离开乡村地区等一系列的改变,让更多妇女们找到了工作,贴补家用。
(2)“表示未来可能发生的某事”
例子:
They say it California needs to find a way to provide for the growing need for water.
他们表示,如果水需求量不断增加,加利福尼亚就需要寻求一中心解决方法。”
第三种用法:
Provide后面接直接宾语 时,通常用to/for 。
Provide sth. to/for 将某物给予给某人”
例子:
The company provides health insurance for/to all of its employees.
该公司为所有员工缴纳医疗保险。
Health issurance 是直接宾语,员工是间接宾语。
PS:
Provide sth. for sb. 的用法更普遍
Provide sth. to sb. 的用法更新颖
那么我的小可爱们,你还记得上一课的知识吗?
我们来做个题检测一下吧!
下面横线内填什么呢?
Your necklace is very nice. ——,where did you buy this necklace.
A.By the way B.Mind you
为什么 suggest 后不能接 to do?
1.
首先我想解决这个问题下的争议。
现代语言学(包括语法)有个基本前提性的结论,即语言是一种convention,即社会的约定俗成。这里有两点值得注意:
这个「约定俗成」不是完全随意的,背后有规律可循。从语言实例中归纳总结出「规律」就是语言学,「规律」被总结出来之后自然就表现出比较强的规范性(prescriptive),变成了「规则」,「规则」在一段时间之内相对比较稳定,因此可以用以判断语言的「对错」。
这个「约定俗称」得是社会性的。不能随便找两个人来创造一个新的「规则」,因为社会普遍意义上不认同。所以大部分「新用法」都被视为是错误的,都消失在历史长河中,只有少数被社会普遍接受之后才能纳入上述的「规则」范畴之内,语言就是这样缓慢生长的。
综合以上两点,自然就能看出来,「规则」相比「语言实例」总是滞后的。可能某个用法很多人都在用了,但是主流规则还是不承认。举几个中文的例子,比如「男主角」现在很多念「男主jiǎo」了,比如「气氛」很多人都念「气fèn」,比如「细思极恐」「十动然拒」等词现在很流行了,但是在高考语文考卷上这样用是要失分的,在正式书面文件上这样用也是要被读者皱眉头的。
现在来看英语。我们作为外国人学英语,当然是想学decent English/ standard English——虽然英语没有「普通话」考试,但是SAT、ACT仍然考语法,也有的是语法书可以参考。碰到有争议的新新用法的时候,我一般建议大家适当保守,选用稳妥的被普遍接受的用法。至于某些native speaker选用这些新新用法,能听懂就行,自己不要用。像我在美国,碰到不规范的英文用法、发音多了去了,我听听就行,自己坚持用的还是当年在人教版上学的正式的、标准的decent English。不要迷信native spaker,native speaker也有教育水平低的嘛,即便是高教育水平的native speaker也会犯错的嘛。我就教过英美澳的老外英语语法——这没什么稀奇,一个本硕博都学中文的美国人如果来纠正咱汉语的语病,只要讲的有道理,咱也会接受的对吧。
具体到suggest后能不能接to do的争议。也许有不少native speaker说suggest to do,但是显然这种用法没有被接受为decent English/ standard English的「规则」之内。
从词源来看,suggest = suggerere = sub- ‘from below’ + gerere ‘bring’,即「从下提起」「提出」(以供他人考虑)的意思,那么后面自然接名词性的成分,即:
名词:Ruth suggested a vacation.
动名词:I suggested going in my car.
名词性从句:I suggest that we wait a day or two.
值得仔细分析的是第三种情况,「that we wait a day or two」即便we换成he/she,后面还是用wait。正因为suggest是「提出」(以供他人考虑),所接从句的内容应该是将来性的(即下例的shall),同时又应该是一种虚拟的将来性(即建议方也并不确定这种将来性是否会成真),所以要用将来时态的虚拟语气(即下例的should)。如果这样说难以理解,也可以简单理解成「客气」(类似于Could you please...中的could表示客气)。如果还是难以理解,还可以简单理解成「应该」,即「我建议你应该怎么做」。
当然,以上分析仅针对suggest做「提出」(以供他人考虑)或者一般翻译的「建议」的意思,suggest还可以表示「暗示」,那就不需要用虚拟语气,用正常语气即可:
Are you suggesting I’m lazy?
for的用法详解,C语言for循环完全攻略
for 循环语句的一般形式为:
for (表达式1; 表达式2; 表达式3)
{
语句;
}
首先要强调两点:
1) 表达式1、表达式2和表达式3之间是用分号;隔开的,千万不要写成逗号。
2) for(表达式1;表达式2;表达式3)的后面千万不要加分号,很多新手都会犯这种错误——会情不自禁地在后面加分号。
因为 for 循环只能控制到其后的一条语句,而在C语言中分号也是一个语句——空语句。所以如果在后面加个分号,那么 for 循环就只能控制到这个分号,下面大括号里面的语句就不属于 for 循环了。
下面来看看它的执行过程:
求解表达式1。
求解表达式2。若其值为真,则执行 for 语句中指定的内嵌语句,然后执行第3步;若表达式2值为假,则结束循环,转到第5步。
求解表达式3。
转回上面第2步继续执行。
循环结束,执行 for 语句下面的语句。
从这个执行过程中可以看出,“表达式1”只执行一次,循环是在“表达式2”“表达式3”和“内嵌语句”之间进行的。
for语句最简单的形式是:
for (循环变量赋初值; 循环条件; 循环变量增值)
{
语句;
}
下面给大家写一个程序,求 1+2+3+4+…+100 的总和。
# includeint main(void){ int i; int sum = 0; //sum的英文意思是“总和” for (i=1; i<=100; ++i) //++是自加的意思, ++i相当于i = i + 1 { sum = sum + i; /.价于sum += i;但是不建议这么写, 因为sum = sum + i看起来更清楚、更舒服. } printf("sum = %dn", sum); return 0;}
输出结果是:
sum = 5050
这个程序的功能是实现求 1+2+3+4+…+100 的和,如果不用循环,加一次就要一条语句,加 100 次就要 100 条语句。这里是从 1 加到 100,要是从 1 加到 10000 那就要 10000 条语句。但有了循环就很方便了,你想加到多少就加到多少,只要改一个参数就可以了。所以循环很重要。
下面按照执行过程看看上面这个程序是怎样执行的。
1) 首先定义一个循环变量 i。定义的时候可以不给它赋初值,在 for 循环里面再给它赋初值也行。但前面说过,最好在定义变量的时候就对它进行初始化,如果值不确定就初始化为 0。所以程序中也可以在定义 i 的时候就给它赋初值,那么 for 循环里的“表达式1”就可以省略了,但分号不可以省略。
这样的话,执行的时候就跳过第1步,直接进入第2步,其他的不变。所以程序也可以像下面这样写:
# includeint main(void){ int i = 1; int sum = 0; for (; i<=100; ++i) { sum = sum + i; } printf("sum = %dn", sum); return 0;}
当然表达式1加上也行,大不了再重新赋一次值。
2) 然后定义一个用来存放“和”的变量 sum,并给它赋初值 0,然后进入 for 循环:
首先求解表达式1,即给变量i赋初值,i=1;表达式1只执行这一次,下面都不会再执行了。
然后求解表达式2,若 1<=100 成立,则执行 for 循环中的内嵌语句,即 sum=0+1。
然后执行第3步,变量 i 自加 1,即变量 i 由 1 变为 2。
然后再求解表达式2,2<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2。
然后再执行第3步,变量 i 自加 1,即变量 i 由 2 变为 3。
然后再求解表达式2,即 3<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2+3。
……
就这样一直循环下去,直到 ++i 等于 100 的时候,求解表达式2,即 100<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2+3+…+100。
然后再执行第3步,变量 i 自加 1,即变量 i 由 100 变为 101。然后再求解表达式2,即 101<=100 不成立,则结束循环,执行 for 循环下面的语句即 printf。
以上就是这个程序的执行过程。关于 for 语句的代码规范化问题,有两点要再跟大家强调一下:
1)if、else、for、while、do 都只能控制到其后的一条语句,如果要控制多条语句必须加大括号{}。但基于代码规范化,if、else、for、while、do 后面的执行语句不论有多少行,就算只有一行也要加{}。
2) 像 if、for、while 等关键字之后应留一个空格再跟左括号(,以突出关键字。
此外上面的程序还有一个知识点要跟大家说一下:从功能上讲,for(i=1; i<=100;++i)完全可以写成for(i=1; i<101; ++i),而且建议大家尽量使用这种写法。也就是说,循环语句的循环条件尽量写成半开半闭的,不管是 for 循环还是 while 循环。
for(i=1; i<101; ++i)实际上是 1≤i<101,是半开半闭的;而for(i=1; i<=100; ++i)实际上是 1≤i≤100,是全闭的。那么为什么建议使用半开半闭的呢?因为如果写成 i<=100 的话,那么每次判断的时候都要判断两次,即 i<100 和 i==100,而写成 i<101 的话每次只需要判断一次。
也许有人说:程序在执行 i<=100 的时候不是将它转换成 i<100||i==100 吗?这样由“短路或”的知识可知,如果前面的为真那么后面的不就不会执行了吗?这样不也是判断一次吗?不是这样的,系统是不会将 i<=100 转换成 i<100||i==100 的,每次判断的时候 i<100 和 i==100 都要判断。
但是写成半开半闭也有一个问题,就是会影响对代码的理解。有时候写成全闭的区间理解起来才顺畅,而写成半开半闭反而不易理解,比如<=右边是变量或表达式的时候。这时候要以可读性为第一要素,即哪种好理解就使用哪种。现在 CPU 速度那么快,也不在乎那点效率。所以前面说“尽量”,没有要求一定要那样写。
下面再给大家写一个程序,求 1 到 100 之间所有奇数的和。
# includeint main(void){ int i; int sum = 0 ; for (i=1; i<100; i+=2) //i+=2;等价于i = i + 2; { sum = sum + i; } printf("sum = %dn", sum); return 0;}
输出结果是:
sum = 2500
关于自增和自减
一直以来,++ 和 –– 语法浪费了太多人的时间。说句实在话,++ 和 –– 在C语言中根本就不重要,除了表达简练外,真的没有什么其他好处了。
简单地说:++i 和 i++ 在单独使用时,都表示 i=i+1;––i 和 i–– 在单独使用时,都表示 i=i–1。
而 a=++i 就相当于 i=i+1,a=i;a=i++ 就相当于 a=i,i=i+1。
同理,a=––i 就相当于 i=i–1,a=i;a=i–– 就相当于 a=i,i=i–1。
如果实在搞不明白 ++ 和 –– 是怎么回事,那也不是什么天塌下来的事情。因为a=++i;完全可以写成i++; a=i;。而a=i++;也完全可以写成a=i; i++;。而且,这也是一种很好的程序风格。
作为一个优秀的程序员,在你的程序中就不应该体现出 ++i 和 i++ 的区别,要么都用 ++i,要么都用 i++,不要一会儿用 ++i 一会儿用 i++。
对于自增和自减还有一点需要强调的是:只有“变量”才能进行自增和自减!你认为 3++ 等于多少?C语言中没有这种写法,常量是不能进行自增和自减的。
for循环练习
1) 求 1! + 2! + 3! + ... + n!
# includeint main(void){ int n = 0; int i = 0; int m = 1; int sum=0; printf("请输入n的值:"); scanf("%d", &n); for (i=1; i<=n; ++i) { m = m .i; sum = sum +m; } printf ("sum = %dn", sum); return 0;}
这个程序虽然短,但逻辑性很强,算法很好,所以建议读者记住。因为逻辑性强,所以只看是很难明白的,自己在纸上试一下,将自己当成计算机一步步地计算就明白了。
假如 n=4:
当 i=1 时,m=1,sum=1。
当 i=2 时,m=1×2,sum=1+1×2。
当 i=3 时,m=1×2×3,sum=1+1×2+1×2×3。
当 i=4 时,m=1×2×3×4,sum=1+1×2+1×2×3+1×2×3×4。
看出规律来了吗?m 的值是一直往下乘,乘以 i 之前 m 的值是(i–1)的阶乘,乘以 i 之后 m 的值就是 i 的阶乘了。这样 i 循环到多少,m. 就立刻将这个数的阶乘计算出来,然后加到 sum 中。
2) for 和 if 的嵌套使用。求 1 到 100 之间所有能被 3 整除的数之和。
# includeint main(void){ int i; int sum = 0; for (i=3; i<100; ++i) { if (0 == i%3) { sum = sum +i; } } printf("sum = %dn", sum); return 0;}
输出结果是:
sum = 1683
大家想想如果不用 if,这个程序能不能写出来?当然能,能被 3 整除的数肯定是 3 的倍数,只要 i 每次自加 3 就行了。我们将这个程序写一下:
# includeint main(void){ int i; int sum = 0; for (i=3; i<100; i+=3) { sum = sum +i; } printf("sum = %dn", sum); return 0;}
因为 ++i 每次只加 1,而 i+=3 每次加 3,所以这种写法与第一种写法比较起来计算机少执行很多步,所以执行起来更快。由此可知,完成相同的功能,算法不一样则效果就不一样。对计算机而言当然是执行得越快越好。
3) 编写程序,输出 1~1000 之间所有的完全平方数。
# include# include//要用sqrt()int main(void){ int i; //循环变量 int x; //存储每个数的二次方根 for (i=1; i<1000; ++i) { x = sqrt(i); /.果i不是完全平方数, 那么sqrt(i)肯定是小数, 而i是int型, 所以x是sqrt(i)取整后的值, 这样x.肯定不等于i. if (x. == i) { printf("%dt", i); // t是跳到下一个Tab位置 } } printf("n"); return 0;}
输出结果是:
1 4 9 16 25 36 49 64 81 100
121 144 169 196 225 256 289 324 361 400
441 484 529 576 625 676 729 784 841 900
961
其实这个程序还有更简单的算法,不需要使用 sqrt()。下面将这个程序也写下来:
# includeint main(void){ int i; //循环变量 for (i=1; i.<1000; ++i) { printf("%dt", i .i); // t是跳到下一个Tab位置 } printf("n"); return 0;}
输出结果是:
1 4 9 16 25 36 49 64 81 100
121 144 169 196 225 256 289 324 361 400
441 484 529 576 625 676 729 784 841 900
961
provide的用法和辨析
上一篇:Promise的基本用法
下一篇:suggest用法详解