ES6 - 約束の使い方
参考:https://www.jianshu.com/p/7e60fc1be1b2
プロミスコンセプト
いわゆる約束は、それは単に将来的にいつか終わるイベント(通常は非同期操作)の結果を保持するコンテナです。構文的には、約束がオブジェクトである、あなたはそれの非同期操作からメッセージを取得することができます。統一されたAPIを提供することを約束し、非同期操作の様々な同じように扱うことができます。 プロミスオブジェクトは、次の2つの特徴を持っています。 ( 1 状態)は、外部の影響を受けません。保留(進行中)、成就(成功)と拒否(失敗):約束のオブジェクトは、非同期操作を表し、3つの状態があります。非同期操作の結果だけでは、あなたは、他の操作がその状態を変更することはできません現在の状態の種類を決定することができます。これは、英語で「約束」を意味名前の由来である約束、彼は他の手段を変更することはできませんと述べました。 ( 2 )状態変化と、それは変更されない、任意の時点で、この結果を得ることができます。プロミスオブジェクトは状態、2つのだけの可能性を変更:満たされ、拒否になるために保留中の変更から保留から。これら二つのものが凝固状態で発生する限り、それは変更されませんし、その結果を維持します、そして解決と呼ばれる(確定します)。変更が発生した場合は、すぐにこの結果を取得するオブジェクトを約束するコールバック関数を追加します。このイベント(イベント)は、イベントの特徴は、あなたがそれを逃した場合には、耳を傾けて行く、結果ではないが、完全に異なっています。 この章の後半でのみ満たさ解決統一状態を指し、起草を容易にするために、拒否された状態が含まれていないことに注意してください。 プロミスオブジェクトと、プロセスは同期動作と非同期動作が深くネストされたコールバック関数を回避するために、発現させることができます。 非同期動作の制御が容易になるように、さらに、プロミスオブジェクトは、統一されたインタフェースを提供します。 約束はまた、いくつかの欠点を有しています。まず第一に、あなたは約束をキャンセルすることはできません新しいが途中でキャンセルすることができないと、それが直ちに実行されます。第二に、あなたはコールバック関数を設定しない場合は、約束 内部エラーがスローされ、外部には反応しません。第三の、係属中のとき の状態、進行状況は、現在のステージは、(最初または近づい完了)を知る方法はありません。 特定のイベントが繰り返し発生し続ける場合は、一般的には、ストリームモードを使用するよりもプロミスの展開で より良い選択。
約束は、コンストラクタのパラメータを(このパラメータが関数である)を受信し、2つの引数:解決は、成功したコールバック関数の非同期操作の実施後、それぞれ拒否
コールバックとポスト非同期実行に失敗。実際には、ここで「成功」と「失敗」は、標準条件に従って、説明状態はfullfiledの約束に設定されている解決するために正確ではない
状態を拒否するとの約束を拒否され設定されています。
01、基本的な使い方
ES6が所定の、プロミスオブジェクトがインスタンスプロミスを生成するコンストラクタです
約束の基本的な構造
ステップ荷重によるステップは、コールバック地獄を引き起こしました
/ * //これは、ステップコールバック地獄によって負荷ステップが発生します 。=新しい新しい画像()VaRのIMGを img.src = "./ IMG / 3-.JPG。"; img.onload =機能(){ VAR =新しい新しいIMGイメージを(); img.src = "./ IMG / 4- / JPG "; img.onload =関数(){ VARのIMG =新たな新たな画像(); img.src =" ./ IMG / 5 / JPG"; IMG =関数.onload(){ VARのIMG =新たな新たな画像(); img.src = "./ IMG / 5,6 / JPG"; } } } / *
基本的な構造:
/ * ヴァール=新しい新しい約束の約束(機能(解決、拒否){ VARのIMG =新しい新しい画像(); img.src = "./img/3-.jpg"; img.onload =機能(){ //ロードに成功解決(本)パラメータは、この渡され 、解決(この) ;} img.onerror =関数(){ //読み込みエラーを (「ロードに失敗」)拒絶; } }); //これは、約束の一例であるが、また直接.then()接続 promise.then(関数(データ){ にconsole.log(データ、 "__________"); }関数(誤差){ にconsole.log(エラー、 "========" ); })/ *
関数loadImg(SRC){ 戻り 、新たな約束(関数(RES、REJ){ VARの IMG = 新;イメージ() img.onload = 関数(){ RES(この); }; img.onerror = 関数(){ REJ( "加载错误" ); }; img.src = SRC; }); } VARの ARR = []; loadImg( "./img/3-.jpg")。その後、(機能(データ){ arr.push(データ)。 戻り loadImg( "./ IMG / 4-.JPG"を) }、関数(誤差){ にconsole.log(エラー) })を(関数(データ){ にconsole.log(データ); // <IMG SRC = '/ / 4-.JPG IMG'> arr.push(データ) はconsole.log(「ARR === >」、ARR); } 関数(誤差){ にconsole.log(エラー); })
非同期ロード画像
機能のgetImage(SRC){ 返す 新しい新しい約束(関数(RES、REJを){ ましょうIMG = 新しい新しい画像(); img.src = SRC; img.onload = 機能(){ // 正常にロードされ RES(IMG); }; img.onerror = 関数(){ // ローディングエラー REJ( "ローディングエラー" ) } }) }
オブジェクトをインスタンス化します
/ * 約束=のgetImage( "./ IMG / 3-.JPG")しましょう。 promise1 = promise.then(RES => {せ にconsole.log(本) はconsole.log( 'のRES --->'、RES) のgetImage( "./ IMG / 4-.JPG")を返します; } REJ => { にconsole.log(REJ); }); promise2 = promise1.then(RES => {せ にconsole.log(本) にconsole.log(RES) のgetImage( "./ IMG / 5-.JPG")を返します })。 promise3 = promise2.then(RES => {せ にconsole.log(本) にconsole.log(RES) のgetImage( "./ IMG / 6-.JPG")を返します })。
チェーン非同期
/ * *链式异步 * * * / / * のgetImage( "./ IMG / 3-.JPG")、次いで(関数(データ){ にconsole.log(本) にconsole.log(データ) のgetImageを返します( "./img/4-.jpg "); })を(RES => { にconsole.log(本) にconsole.log(RES) のgetImage(" ./ IMG / 5-.JPG")を返します。 。})を(関数(データ){ にconsole.log(本) のgetImage( "./ IMG / 6-.JPG")を返します })/ *
.then(RES => {}、REJ => {})
/ * 2つのパラメータがあり、関数であり、最初の関数呼び出しが成功した関数であり、第二の機能は、関数呼び出しが失敗している のgetImage(「./ IMG / 1- .JPG」)をし(関数(データ){ console.log(データ); }関数(ERR){ にconsole.log(ERR); })* / // キャッチ:故障後メソッドの実装は、パラメータがあり、パラメータが失敗した後に行う、関数である / * のgetImage( 」./img/1-.jpg").then(function(データ){ にconsole.log(データ); })キャッチ(関数(ERR){ にconsole.log(ERR); })/ *
Promise.all
/ * * Promise.allは、 複数の非同期の配列を行います。障害が発生した状態を拒否すべき最初の値が返されたときに成功リストからなるアレイのすべての結果を返し、失敗しました。 * * * / LET一覧 = []; のための(I = LET 3; I 80を<; I ++は){ list.push(のgetImage( "./img/" + I + "-.jpg" )); } / * Promise.all(リスト).then(関数(ARR){ にconsole.log(ARR); arr.forEach(T =>にconsole.log(t.src)); }); / *
Promise.race
/ * * レース レース 非同期アレイの複数を実行*、非同期完了するために最初、戻り方 * * * * / Promise.race(リスト).then(関数(データ){ にconsole.log(データ); })
マイクロチャネルのマイクロチャネルの非同期は、アプレットマップのAPIを呼び出します
<!--form表单--> <form bindsubmit="formSubmit"> <!--输入起点和终点经纬度坐标,格式为string格式--> <label>起点坐标: <input style="border:1px solid #000;" name="start" value="鼓楼"></input> </label> <!--多个终点位置示例:39.984060,116.307520;39.984060,116.507520--> <label>终点坐标: <input style="border:1px solid #000;" name="dest"value="火车站"></input> </label> <!--提交表单数据--> <button form-type="submit">计算距离</button> </form> <!--渲染起点经纬度到终点经纬度距离,单位为米--> <view wx:for="{{distance}}" wx:key="index"> <view>起点到终点{{index+1}}的步行距离为{{item}}米</view> </view>
import myPromise from '../../utils/myPromise.js' import calculatePromise from '../../utils/calculatePromise.js' Page({ /** * 页面的初始数据 */ data: { distance: [], startPos:{}, destPos:{} }, //在Page({})中使用下列代码 //事件触发,调用接口 formSubmit(e) { //将输入的地名转化为经纬度 const startPlace = e.detail.value.start const destPlace = e.detail.value.dest myPromise({addr:startPlace}).then(res=>{ console.log(res) this.setData({ startPos: res.result.location }) }).then( myPromise({ addr: destPlace }).then(res => { console.log(res) this.setData({ destPos: res.result.location }) }) ).then(res2 => { console.log('===>', this.data) const newStartPos = `${this.data.startPos.lat},${this.data.startPos.lng}` const newDestPos = `${this.data.destPos.lat},${this.data.destPos.lng}` console.log(newStartPos,newDestPos) calculatePromise({ start: newStartPos, dest: newDestPos }).then(res => { //成功后的回调 console.log('计算距离的成功回调::', res); var res = res.result; var dis = []; for (var i = 0; i < res.elements.length; i++) { dis.push(res.elements[i].distance); //将返回数据存入dis数组, } this.setData({ //设置并更新distance数据 distance: dis }); } ) }) } })
// 引入SDK核心类 var QQMapWX = require('../libs/qqmap-wx-jssdk.js'); // 实例化API核心类 var qqmapsdk = new QQMapWX({ key: '2BJBZ-TKDRU-NVMV4-2JAJC-VK2Y2-M7F3D' // 必填 }); export default function calculatePromise(options) { return new Promise((resolve, reject) => { //调用距离计算接口 qqmapsdk.calculateDistance({ //mode: 'driving',//可选值:'driving'(驾车)、'walking'(步行),不填默认:'walking',可不填 //from参数不填默认当前地址 //获取表单提交的经纬度并设置from和to参数(示例为string格式) from: options.start || '', //若起点有数据则采用起点坐标,若为空默认当前地址 to: options.dest, //终点坐标 success: resolve, fail:reject }); }) }
// 引入SDK核心类 var QQMapWX = require('../libs/qqmap-wx-jssdk.js'); // 实例化API核心类 var qqmapsdk = new QQMapWX({ key: '2BJBZ-TKDRU-NVMV4-2JAJC-VK2Y2-M7F3D' // 必填 }); export default function myPromise(options) { return new Promise((resolve, reject) => { //解析地名 并转化为经纬度 qqmapsdk.search({ keyword: options.addr, success: res1 => { console.log('地名查询--->', res1); const address = res1.data[0].address qqmapsdk.geocoder({ address: address, success: resolve, fail: reject }) } }) }) }