Heim > Web-Frontend > js-Tutorial > Hauptteil

Versprechen verstehen, asynchron, warten

hzc
Freigeben: 2020-07-04 09:50:13
nach vorne
1895 Leute haben es durchsucht

Im vorherigen Artikel ging es hauptsächlich um Synchronisation und Asynchronität, den „Ausführungsstapel“, die „Nachrichtenwarteschlange“ sowie die daraus abgeleiteten „Makroaufgaben“ und „Mikroaufgaben“. Wenn Sie diese Konzepte verstehen Wenn Sie nicht viel darüber wissen, können Sie zu diesem Link gehen:

https://www.jianshu.com/p/61e7844e68d8

Sowohl Makroaufgaben als auch Mikroaufgaben sind asynchron, einschließlich Ajax Anfragen und Timing. Lassen Sie uns ein vorläufiges Verständnis von Versprechen haben und wissen, dass es eine Möglichkeit ist, asynchrone Probleme zu lösen.

Weil es viele Wissenspunkte erfordert In diesem Artikel geht es hauptsächlich um Rückruffunktionen und -versprechen:

1. Die Rückruffunktion

先上代码:
function f2() {
    console.log('2222')
}
function f1(callback){
    console.log('111')
  setTimeout(function () {
    callback(); 
  }, 5000);
  console.log('3333')
}
f1(f2);

先看下打印值是:
111
3333
五秒后2222
Nach dem Login kopieren

entspricht der Ausführung des Hauptthreads, und die Funktion f2 wird aufgerufen über die Callback-Funktion. Daran ist nichts auszusetzen. Aber schauen Sie sich das folgende Beispiel an:

现在我们读取一个文件,fileReader就是一个异步请求

// 这个异步请求就是通过回调函数的方式获取的

var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file, 'utf-8',function(err, data){
    if(err){
        console.log(err)
    } else {
        console.log(data)
    }
})
Nach dem Login kopieren

Es sieht jetzt sehr gut aus, aber wenn beim Hochladen der Datei ein Fehler auftritt, müssen wir im Rückruf ein Urteil fällen. Wenn wir mit dem Lesen dieser Datei fertig sind, müssen wir dies tun mehrere lesen Wo sind die Dateien? Sollte es so geschrieben werden:

读取完文件1之后再接着读取文件2、3

var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file1, 'utf-8',function(err1, data1){
    if(err1){
        console.log(err1)
    } else {
        console.log(data1)
    }
    reader.readAsText(file2, 'utf-8',function(err2, data2){
        if(err2){
            console.log(err2)
        } else {
            console.log(data2)
        }
        reader.readAsText(file3, 'utf-8',function(err3, data3){
            if(err3){
                console.log(err3)
            } else {
                console.log(data3)
            }
        })
    })
})
Nach dem Login kopieren

Es so zu schreiben kann die Anforderungen erfüllen, aber die Lesbarkeit dieses Codes ist relativ schlecht und er sieht nicht so elegant aus, was wir oft als „Callback-Hölle“ bezeichnen. . Wie kann man diesen verschachtelten Rückruf knacken? ES6 bietet uns Versprechen:

2. Versprechen

Lassen Sie uns zunächst verstehen, was ein Versprechen im wahrsten Sinne des Wortes ist. Versprechen kann in Engagement und Garantie übersetzt werden:

Meine Freundin hat mich gebeten, etwas zu tun, aber ich verspreche, dass es ein Ergebnis für Sie geben wird. Erfolg (erfüllt) oder Misserfolg (abgelehnt) und ein Wartestatus (ausstehend).

还是先上例子

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2000) // 成功以后这个resolve会把成功的结果捕捉到
        // reject(2000) // 失败以后这个reject会把失败的结果捕捉到
    }, 1000)
    console.log(1111)
})

promise.then(res => {
    console.log(res) // then里面第一个参数就能拿到捕捉到的成功结果
}, err =>{
    console.log(res)// then里面第二个参数就能拿到捕捉到的失败结果
})

打印结果:

1111
2000(一秒以后)
Nach dem Login kopieren

1. Then-Kettenoperation

Die then-Methode des Promise-Objekts gibt ein neues Promise-Objekt zurück, sodass die then-Methode über die Kette aufgerufen werden kann. Die

then-Methode empfängt zwei Funktionen als Parameter. Der erste Parameter ist der Rückruf, wenn Promise erfolgreich ausgeführt wird, und der zweite Parameter ist der Rückruf, wenn die Ausführung von Promise fehlschlägt Parameter erfassen den fehlgeschlagenen Rückruf.

Es wird nur eine der beiden Funktionen aufgerufen.
Deine Freundin bittet dich, Tomaten-Eier-Suppe zuzubereiten. Entweder du tust es oder du bestellst es zum Mitnehmen. Es gibt definitiv keine dritte Option.

Der Rückgabewert der Funktion wird verwendet, um das bis dahin zurückgegebene Promise-Objekt zu erstellen. Wie ist dieser Satz zu verstehen? Immer noch das obige Beispiel:

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2000)
    }, 1000)
    console.log(1111)
})
promise.then(res => {
    console.log(res) // 这个地方会打印捕捉到的2000
    return res + 1000 // 这个函数的返回值,返回的就是这个promise对象捕捉到的成功的值
}).then(res => {
    console.log(res) //这个地方打印的就是上一个promise对象return的值
})

所以打印顺序应该是:

1111
2000
3000
Nach dem Login kopieren

Gerade haben wir gesehen, dass dann zwei Parameter akzeptiert werden, einer ist ein Erfolgsrückruf und der andere ein Fehlerrückruf. Darüber hinaus scheint es nicht so elegant zu sein Bietet eine Catch-Methode. :

2. Catch-Erfassungsvorgang

Dieser Catch ist speziell für die Erfassung von Fehlerrückrufen konzipiert:

let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(2000) // 失败以后这个reject会把失败的结果捕捉到
    }, 1000)
    console.log(1111)
})
promise.catch(res => {
    console.log(res) // catch里面就能拿到捕捉到的失败结果
})

打印结果:

1111
2000(一秒以后)
Nach dem Login kopieren

Zusätzlich zu then und fangen, versprechen hat auch Wir verwenden auch die beiden Syntaxen all und race, kurz:

3, all

Jetzt haben wir eine solche Anforderung. Es gibt drei Schnittstellen A, B, und C. Drei sind erforderlich. Nachdem alle Schnittstellen erfolgreich waren, kann die vierte Anfrage initiiert werden.

Verkettete Aufrufe

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    resolve()
}).then(res => {
    let getInfoB = new Promise((resolve, reject) => {
        console.log('小B开始执行了')
        resolve()
    }).then(res => {
        let getInfoC = new Promise((resolve, reject) => {
            console.log('小C开始执行了')
            resolve()
        }).then(res => {
            console.log('全都执行完了!')
        })
    })
})
Nach dem Login kopieren

Es ist eine Schicht in der anderen, es scheint nicht so elegant zu sein

alle

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    resolve()
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    resolve()
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    resolve()
})
Promise.all([getInfoA, getInfoB, getInfoC]).then(res => {
   console.log('全都执行完了!')
})
Nach dem Login kopieren

Erhält ein Array von Promise-Objekten als Parameter: Wenn der Status aller Promise-Objekte in diesem Array aufgelöst oder abgelehnt wird, wird die Methode then aufgerufen. So perfekt, so elegant.

4. Rennen

Jetzt gibt es noch eine weitere Anforderung, nämlich Schnittstelle A, B, C. Solange eine davon antwortet, kann ich Schnittstelle D anpassen. Also wie man es implementiert ?

1. Traditionelle Methode

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    setTimeout((err => {
        resolve('小A最快')
    }),1000)
}).then(res =>{
    console.log(res)
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    setTimeout((err => {
        resolve('小B最快')
    }),1001)
}).then(res =>{
    console.log(res)
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    setTimeout((err => {
        resolve('小C最快')
    }),1002)
}).then(res =>{
    console.log(res)
})

打印结果

小A开始执行了
小B开始执行了
小C开始执行了
小A最快
Nach dem Login kopieren

Diese Methode muss dreimal geschrieben werden, und sie scheint nicht so elegant zu sein. Schauen wir uns an, wie man Rasse schreibt.

2. Rennen

let getInfoA = new Promise((resolve, reject) => {
    console.log('小A开始执行了')
    setTimeout((err => {
        resolve('小A最快')
    }),1000)
})
let getInfoB = new Promise((resolve, reject) => {
    console.log('小B开始执行了')
    setTimeout((err => {
        resolve('小B最快')
    }),1001)
})
let getInfoC = new Promise((resolve, reject) => {
    console.log('小C开始执行了')
    setTimeout((err => {
        resolve('小C最快')
    }),1002)
})
Promise.race([getInfoA, getInfoB, getInfoC]).then(res => {
    console.log(res)
})

打印结果

小A开始执行了
小B开始执行了
小C开始执行了
小A最快
Nach dem Login kopieren

Ähnlich wie Promise.all verwendet Promise.race ein Array aus Promise-Objekten als Parameter. Der Unterschied besteht darin, dass eines der Promise-Objekte im Array ist Wenn sich der Promsie-Status in „Gelöst“ oder „Abgelehnt“ ändert, kann die .then-Methode aufgerufen werden.

Promise ist eine Methode, die von ES6 zur Lösung asynchroner Probleme verwendet wird. Sie wird beispielsweise häufig verwendet, ist durch Promise gekapselt und sehr bequem zu verwenden.

Zusätzlich zu den Versprechen bietet uns ES6 auch die ultimativen Tricks „Async“ und „Await“. Da diese beiden Wissensblöcke relativ groß sind, werden wir im nächsten Artikel darüber sprechen.

Persönlicher öffentlicher WeChat-Account: Wenn Jerry etwas zu sagen hat, veröffentlicht er normalerweise einige technische Artikel und Lesenotizen. Willkommen zur Kommunikation.

Empfohlenes Tutorial: „JS-Tutorial

Das obige ist der detaillierte Inhalt vonVersprechen verstehen, asynchron, warten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:jianshu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage