当前位置: 首页 > 编程笔记 >

承诺回调和异步/等待

林君博
2023-03-14
本文向大家介绍承诺回调和异步/等待,包括了承诺回调和异步/等待的使用技巧和注意事项,需要的朋友参考一下

首先,我们必须了解两个主要概念

  • 同步编程

  • 异步编程

同步编程

它等待每个语句完成执行,然后再转到下一条语句。

如果语句不相互依赖,但是由于它们在队列中,它们仍在等待执行,则此方法可能会减慢应用程序的速度。

异步编程

在移动到下一条语句之前,它不等待当前语句完成执行。例如,调用Web服务并使用JavaScript执行文件复制。

调用Web服务可能需要一些时间才能返回结果,同时我们可以完成其他一些操作。

服务器提供结果后,我们无需等待就可以对其进行处理。

我们的三种方法1.回调2.承诺3.异步/等待处理异步编程。

回调

const articles = [
   {title:'First article'},
   {title:'Second article'}
];
function getArticles(){
   setTimeout(()=>{
      let articleContent='';
      articles.forEach((article,index)=>{
         articleContent+=`${article.title}`+` `;
         });
         console.log(articleContent);
      },1000);
   };
getArticles();

在这里,我们仅创建了一个商品数组,并在1秒钟后打印在控制台上。

将setTimeout函数与1秒时间配合使用只是为了展示服务器行为。

现在,如果我们通过另一个功能将新文章添加到上述列表中,该怎么办

function createArticle(article){
   setTimeout(()=>{
      articles.push(article);
   },2000);
}

如果我们现在先用新文章先调用createArticle,然后再用getArticle进行调用,那么我们应该获得三篇文章,但是只有前两篇文章

const articles = [
   {title:'First article'},
   {title:'Second article'}
];
function getArticles(){
   setTimeout(()=>{
      let articleContent='';
      articles.forEach((article,index)=>{
         articleContent+=`${article.title}`+` `;
         });
         console.log(articleContent);
      },1000);  
   };
   function createArticle(article){
      setTimeout(()=>{
         articles.push(article);
      },2000);
   }
createArticle({title:'Third article'});
getArticles();
//控制台输出
"First article Second article "

为什么会这样呢?

因为createArticle的执行有2秒的超时,与此同时getArticle完成了执行

示例

const articles = [
   {title:'First article'},
   {title:'Second article'}
];
function getArticles(){
   setTimeout(()=>{
      let articleContent='';
      articles.forEach((article,index)=>{
         articleContent+=`${article.title}`+` `;
      });
      console.log(articleContent);
   },1000);  
};
function createArticle(article, callback){
   setTimeout(()=>{
      articles.push(article);
      callback();
   },2000);
}
createArticle({title:'Third article'},getArticles);
//控制台输出
"First article Second article Third article "

我们使用回调将getArticle的调用嵌套在createArticle中。

请注意,将getArticles作为参数传递给createArticle函数。但是这样,嵌套回调变得复杂

承诺

通过使用promises,我们不需要传递回调函数。承诺有两个论点:解决和拒绝。如果函数成功执行,我们可以调用resolve()其他函数reject()

const articles = [
   {title:'First article'},
   {title:'Second article'}
];
function getArticles(){
   setTimeout(()=>{
      let articleContent='';
      articles.forEach((article,index)=>{
         articleContent+=`${article.title}`+` `;
      });
      console.log(articleContent);
   },1000);
};
function createArticle(article){
   return new Promise((resolve,reject)=>{
      articles.push(article);
      let isError=false;
      if(!isError){
         resolve();
      } else {
         reject();
      }
   });
}
createArticle({title:'Third article'})
.then(getArticles());
//控制台输出
"First article Second article Third article "
handling error with promises:
const articles = [
   {title:'First article'},
   {title:'Second article'}
];
function getArticles(){
   setTimeout(()=>{
      let articleContent='';
      articles.forEach((article,index)=>{
         articleContent+=`${article.title}`+` `;
      });
      console.log(articleContent);
   },1000);
};
function createArticle(article){
   return new Promise((resolve,reject)=>{
      articles.push(article);
      let isError=true;
      if(!isError){
         resolve();
      }else{
         reject('Something went wrong');
      }
   });
}
createArticle({title:'Third article'})
.then(getArticles())
.catch(error=>console.log(error));
//控制台输出
"Something went wrong"

我们从createArticle调用reject并捕获了错误

全部承诺

const promise1=Promise.resolve('Hello');
const promise2=100;
const promise3=new Promise((resolve,reject)=>{
   setTimeout(resolve,2000,'test');
});
Promise.all([promise1,promise2,promise3])
.then((values)=>console.log(values));
//控制台输出
["Hello", 100, "test"]

我们可以将诺言合并到一个数组中,然后使用实际的then语句,而不是在每个诺言之后嵌套then语句

我们可以使用jsonplaceholder的fetch api

const promise0=fetch('https://jsonplaceholder.typicode.com/users').then(res=>res.json());
const promise1=Promise.resolve('Hello');
const promise2=100;
const promise3=new Promise((resolve,reject)=>{
   setTimeout(resolve,2000,'test');
});
Promise.all([promise0,promise1,promise2,promise3])
.then((values)=>console.log(values));

异步/等待

要使用await on语句,该功能应标记为异步

<!DOCTYPE html>
<html>
<head>
<title>Async/Await Example</title>
</head>
<body>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
   const articles = [
      {title:'First article'},
      {title:'Second article'}
   ];
   function getArticles(){
      setTimeout(()=>{
         let articleContent='';
         articles.forEach((article,index)=>{
            articleContent+=`${article.title}`+` `;
         });
         console.log(articleContent);
      },1000);
   }
   function createArticle(article){
      articles.push(article);
   }
   async function testAsync(){
      await createArticle({title:'Third article'});
      getArticles();
   }
   testAsync();
   //控制台输出
   //第一篇第二篇第三篇
</script>
</body>
</html>

testAsync函数被标记为异步,并且我们使用了等待createArticle函数来首先完成它。然后我们打电话给getArticles()

使用async / await是Promise的更好版本,并使代码更简洁

 类似资料:
  • 问题内容: 关于这两个重要来源:NZakas- 承诺链中的归还承诺 和MDN承诺,我想提出以下问题: 每次我们从承诺履行处理程序返回值时,该值如何传递给从同一处理程序返回的新承诺? 例如, 在这个例子中,是一个承诺。也是来自履行处理程序的承诺。但是。取而代之的是神奇地解决(如何?),然后将该值传递给的实现处理程序。即使是这里的句子也令人困惑。 您能给我解释一下这到底是怎么回事吗?我对这个概念感到困

  • 问题内容: 我试图摆脱使用Mongoose Promise与Node.js的async / await功能的束缚。调用我的函数时,我想保存该函数查询的员工列表。同时,内部的语句返回期望的查询,在内部的returns返回,表明我没有正确返回promise。 我对承诺完全陌生,以至于我没有正确理解范例……非常感谢您的帮助。 问题答案: 您需要这样做,否则您正在等待返回的函数。 当前,您正在等待非承诺,

  • 问题内容: 我读到用关键字标记的异步函数隐式返回一个promise: 但这不连贯…假设返回一个诺言,而await关键字将从诺言中返回值,而不是诺言itsef,那么我的getVal函数 应该 返回该值,而不是隐式诺言。 那到底是什么情况?用async关键字标记的函数是隐式返回promise还是控制它们返回的内容? 也许,如果我们不明确地返回某些东西,那么他们会隐式地返回一个诺言…? 更清楚地说,上述

  • 问题内容: 我目前正在等待所有承诺按顺序完成,如下所示: 但是,通过这种方式,配置文件和令牌将顺序执行。由于两者彼此独立,因此我希望两者一起独立执行。我认为可以使用Promise.all完成此操作,但是我不确定语法,也找不到任何帮助。 所以我的问题是如何转换上面的api调用以一起运行,然后返回最终输出。 问题答案:

  • 问题内容: 无论我的Promise是否成功解决,我都想执行相同的操作。我不想将相同的功能绑定到两个参数。没有像jQuery一样的东西吗?如果没有,我该如何实现? 问题答案: 没有像jQuery一样的东西吗? 如果没有,我该如何实现? 您可以这样实现自己的方法: 或更广泛地讲,将解析信息传递给回调: 两者都确保原始解析得以维持(当回调中没有异常时),并确保等待诺言。

  • 问题内容: 我已经开发JavaScript几年了,我完全不了解关于promise的麻烦。 看来我所做的就是改变: 无论如何我都可以使用像async这样的库,它有类似以下内容: 哪个代码更多,可读性更差。我在这里什么都没得到,也不是突然变得神奇地“平坦”。更不用说必须将事情变成诺言。 那么,这里的诺言有什么大惊小怪的呢? 问题答案: 承诺不是回调。许诺代表 异步操作 的 未来结果 。当然,以您的方式