当前位置: 首页 > Web前端 > HTML5

JavaScript在Promise.then方法中返回一个新的Promise

时间:2023-04-04 22:58:45 HTML5

看一个实际的例子:loadScript("/article/promise-chaining/one.js").then(function(script){returnloadScript("/article/promise-chaining/two.js");}).then(function(script){returnloadScript("/article/promise-chaining/three.js");}).then(function(script){//使用脚本中声明的函数//以表明它们确实加载了one();二三();});依次加载one.js、two.js、three.js,当然也可以使用箭头函数语法:loadScript("/article/promise-chaining/one.js").then(script=>loadScript("/article/promise-chaining/two.js")).then(script=>loadScript("/article/promise-chaining/three.js")).then(script=>{//脚本加载完毕,我们可以使用在那里声明的函数one();two();three();});这里每个loadScript调用都会返回一个承诺。当这个新的promise被resolve时,它??会触发下一个.then的执行。所以它开始加载下一个脚本。所以脚本一个一个加载。我们可以向链中添加更多异步操作。请注意,代码仍然是平坦的——它向下生长,而不是向右生长。这样就没有厄运金字塔的迹象。虽然我们可以在then之后直接调用loadScript:loadScript("/article/promise-chaining/one.js").then(script1=>{loadScript("/article/promise-chaining/two.js").then(script2=>{loadScript("/article/promise-chaining/three.js").then(script3=>{//这个函数可以访问变量script1、script2和script3one();two();three();});});});这段代码做同样的事情:按顺序加载3个脚本。但是它向右增长,所以本质上还是存在回调地狱的问题。Thenables对象准确地说,then处理程序可能返回的不完全是一个Promise,而是一个所谓的thenable对象——一个带有.then方法的任意JavaScript对象。它将以与Promise相同的方式对待。这个想法是第3方库可以实现自己的承诺兼容对象。它们可以有一组扩展的方法,但也与原生Promises兼容,因为它们实现了.then。看一个例子:classThenable{constructor(num){this.num=num;}then(resolve,reject){alert(resolve);//function(){nativecode}//在1秒后用this.num*2解析setTimeout(()=>resolve(this.num*2),1000);//(**)}}newPromise(resolve=>resolve(1)).then(result=>{returnnewThenable(result);//(*)}).then(alert);//单步调试1000ms后显示2:第14行newPromise里面的executor被执行,立即resolve,抛出结果1,这会导致代码15然后立即调用第1行的函数,输入参数为1,构造一个新的Thenable对象。JavaScript在第16行检查.then处理程序返回的对象:如果它有一个名为then的可调用方法,它会调用该then方法,提供本机函数解析、拒绝作为参数(类似于执行程序)和等待其中之一他们被称为。在上面的示例中,resolve(2)在1秒(**)后被调用。然后将结果进一步向下传递。因此,单步执行下图中第16行的代码后,会自动进入第8行代码。打印出解析本机函数的本机代码字符串。代码第10行的resolve会触发第18行的第二个then方法: