Promise Asynchronous JavaScript and basic usage (resolve and reject)

Promise to solve the problem
believe that every front-end have encountered a problem when performing an asynchronous tasks need to rely on the results of another asynchronous task, we generally two asynchronous tasks will be nested together, this happens twelve times can also be tolerated, but occurs after many times, on the formation of a so-called callback hell code nested layers, a chain, it is clear, slightly more complex logic, this program will become difficult to maintain. For example, we just yesterday that the callback hell examples:

function funA(callback) {
console.log("A");
setTimeout(() = > {
callback()
}, 100)
}

function funB() {
console.log("B")
}

function funC(callback) {
console.log("C")
setTimeout(() = > {
callback()
}, 1000)
}

function funD() {
console.log("D")
}

function funE() {
console.log("E")
}

function funF() {
console.log("F")
}

funA(() = > {
funB()
funC(() = > {
funD()
})
funE()
})
funF()

 

 

In this case, programmers have come up with many solutions (such as modular code), but on the process control, did not avoid a lot of nesting. But after ES6 standard, the standardization of Promise, to some extent, solve the problem of flow operation of JavaScript.

What is the Promise
there is such a scene in the third chapter "Asynchronous and Performance" in the metaphor Promise:

  Before I went to the snack bar counter, I ordered a cheeseburger. And pay 1.47 dollars in cash. By ordering and payment, I made a request to obtain a value (cheeseburger). I started a business.

  But in general, burgers not immediately to my hands. The cashier handed me something instead of burgers: a receipt for a meal with a line number. This meal is a number, "I owe you" promise (Promise), which promise I'll finally get my burgers.

  So I took my receipt and ordering number. I know it represents my future burgers, so I no longer need to worry about it - except starving!

  When I was waiting, I can do other things, like my friends made micro letter said, "Hey, eat lunch together? I want to eat burgers."

  I have to reason with my future in the burgers, even if it is not to my hands. My brain can do this because it will be ordering number as a placeholder from Burger. The placeholder essentially make this value is independent of time. It is a future value.

  Eventually, I hear, "No. 113!." So I happily took the receipt back to the counter. I handed the cashier a receipt, get my burgers. In other words, once the value of my future ready, I'll use my value in exchange for the promise of the value itself.

  But there is another possible output. They called my number, but when I went to get a burger, I regret to tell the cashier, "I'm sorry, it looks like we burgers sold out." The customer how frustrated this scenario aside we can see a significant future value of the property: they can either indicate success can also mean failure.

  Every time I ordered a burger, I knew I would either end up with a burger or get bad news burgers sold out, and have to consider something else for lunch.

  I changed from wait or not wait until the Hamburg, this process is irreversible,

The above describes the very image of the promise, and get on top of the waiting Hamburg Hamburg, Hamburg sold out, not Hamburg, corresponding to the three states ** pending promise: in progress, neither a success nor a failure state. fulfilled: means that the operation completed successfully. rejected: means that the operation failed. **
basic usage Promise of
grammar

new new Promise ( function (Resolve, Reject) {...}); // Reject parameter is optional

 

Parameter
executor

executor是带有 resolve 和 reject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数, resolve 和 reject 两个函数作为参数传递给executor(executor 函数在Promise构造函数返回新建对象前被调用)。resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。executor 内部通常会执行一些异步操作,一旦完成,可以调用resolve函数来将promise状态改成fulfilled,或者在发生错误时将它的状态改为rejected。
如果在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。

对更多对Promise的描述感兴趣的可以 点击查看MDN Promise下面我们开始上代码

新建一个Promise的实例:

let promise = new Promise((resolve, reject) = > {
setTimeout(() = > {
let random = Math.random()
if (random > 0.5) {
resolve(`resolve$ {random}`)
} else {
resolve(`reject$ {random}`)
}
}, 1000)
})

 

由上所示,Promise的构造函数接收一个函数作为参数,该函数接受两个额外的函数,resolve和reject,这两个函数分别代表将当前Promise置为fulfilled(已成功)和rejected(已失败)两个状态。Promise正是通过这两个状态来控制异步操作的结果。接下来我们将讨论Promise的用法,实际上Promise上的实例promise是一个对象,不是一个函数。在声明的时候,Promise传递的参数函数会立即执行,因此Promise使用的正确姿势是在其外层再包裹一层函数。

 

let run = function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
let random = Math.random()
if (random > 0.5) {
resolve(`resolve:${random}`)
} else {
reject(`reject:${random}`)
}
}, 1000)
})
}

run()

 

 

这是Promise的正常用法,接下来,就是对异步操作结果的处理,接着上面创建的函数run()

run().then(
function(value) {
console.log(value)
})

 


每个Promise的实例对象,都有一个then的方法,这个方法就是用来处理之前各种异步逻辑的结果。

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
下面是一个用Promise对象实现的 Ajax 操作的例子:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript异步</title>
</head>
<body>
<script src="https://unpkg.com/[email protected]/dist/jquery.min.js"></script>
<script>
new Promise((resolve, reject) => {
$.ajax({
url: "https://easy-mock.com/mock/5c249dbe46e8386d0b21b475/example_copy_copy/promisetest",
success: res => {
if (res.code == 0) {
resolve(res.data)
} else {
reject(res.desc)
}
}
});
})
.then(res => {
console.log(res);
},err =>{
console.log(err)
})

</script>

</body>
</html>

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript异步</title>
</head>
<body>
<script src="https://unpkg.com/[email protected]/dist/jquery.min.js"></script>
<script>
    var a = new Promise(
        //下面函数为executor函数,带有 resolve 和 reject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数, resolve 和 reject 两个函数作为参数传递给executor(executor 函数在Promise构造函数返回新建对象前被调用)。
        (resolve, reject) => {
        $.ajax({
            url: "https://api.apiopen.top/musicBroadcasting",
            success: res => {
                if (res.code == 200) {
                    console.log('1',res.result)
                    // resolve()异步回调将promise变为fulfilled(已成功)状态
                    resolve(res.result)//res.message为参数A
                } else {
                    // reject()异步回调将promise变为rejected(已失败)状态
                    reject(res.result)//res.desc为参数B
                }
            }
        });
    })
    // 每个Promise的实例对象,都有一个then的方法,这个方法就是用来处理之前各种异步逻辑的结果(fulfilled(已成功)状态或者rejected(已失败)状态)
    // 第一个回调函数是Promise对象的状态变为resolved时调用,
    // 第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
    .then(res => { 
        console.log('res参数来自resolve(A)传入的参数A',res)
    },err =>{
        console.log('reject(B)传入的参数B',err)
    })
    console.log(a)
        
// 如果异步操作获得了我们想要的结果,那我们将调用resolve函数,在then的第一个作为参数的匿名函数中可以获取数据,如果我们得到了错误的结果,调用reject函数,
// 在then函数的第二个作为参数的匿名函数中获取错误处理数据。
</script>

</body>
</html>

  


当res.code == 0 为接口调用成功 输出:

手动把 上面代码 res.code == 0 改为 res.code == 1 就会抱一个错误,输出:

如果异步操作获得了我们想要的结果,那我们将调用resolve函数,在then的第一个作为参数的匿名函数中可以获取数据,如果我们得到了错误的结果,调用reject函数,在then函数的第二个作为参数的匿名函数中获取错误处理数据。
这样,一个次完整的Promise调用就结束了。对于Promise的then()方法,then总是会返回一个Promise实例,因此你可以一直调用then,形如run().then().then().then().then().then()…
在一个then()方法调用异步处理成功的状态时,你既可以return一个确定的“值”,也可以再次返回一个Promise实例,当返回的是一个确切的值的时候,then会将这个确切的值传入一个默认的Promise实例,并且这个Promise实例会立即置为fulfilled状态,以供接下来的then方法里使用。看代码:

let num = 0
let run = function() {
return new Promise(resolve => {
resolve(`${num}`)})
}

run().then(val => {
console.log(val)
return val
})
.then(val =>{
val++
console.log(val)
return val
})
.then(val =>{
val++
console.log(val)
})

 

输出:

根据这个特性,我们就可以将相互依赖的多个异步逻辑,进行比较顺序的管理了,解决了让人头痛的回调地狱问题。

今天我们就先到这里,明天我们讲一下Promise.then()与Promise.catch()

友情链接:点击查看所有文章目录

友情链接:点击查看 JavaScript异步系列文章目录

原文链接:https://blog.csdn.net/qq_42911663/article/details/85790181

Guess you like

Origin www.cnblogs.com/itgezhu/p/11983943.html