Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
515 views
in Technique[技术] by (71.8m points)

请教一个关于 数据库操作函数 await promise同步的问题?

请教一个关于数据库操作进行同步问题。

问题的背景是要作一系列用户登陆操作,希望能达到根据用户 openID检索用户数据库,有则用库中的用户个人信息初始化接下来的函数,没有则要填入一个基本信息字段后,新增这个用户。

很显然这里的数据库访问 get 跟 新增 add等都是属于异步函数,要进行同步,尤其是新增用户,要选录入一个 信息,再做数据库 add

我个人的习惯是先做一个小demo,将同步机制完成后,再并入 实际的程序中。

然而读了几天官方手册,也看了不少网上的贴子,尝试了3种方式,进行同步,都没能实再想要的效果。

恳请过路的高人前辈帮忙瞅一瞅,应该怎样解决同步的问题。

先上demo中 index.js的代码

//index.js
const regeneratorRuntime = require("../../libs/regeneratorRuntime.js");
const promisify = require('../../libs/promisify.js');
const app = getApp();
const db = wx.cloud.database();

Page({
    data: {
        grade: 0,
        innerData: 0
    },

    onLoad: function () {
        let that = this;        
        console.log('initical data', that.data.innerData);
        // const awfun4 = promisify(that.fun4());
        // const awfun5 = promisify(that.fun5());
        // const awfun6 = promisify(that.fun6());
        that.orderTest();
        // console.log(awfun4);
        // console.log(awfun5);
        // console.log(awfun6);
    },

    orderTest: async function () {
        let that = this;

        await that.fun4();
        console.log('after fun1', that.data.innerData);
        await that.fun5();
        console.log('after fun2', that.data.innerData);
        await that.fun6();
        console.log('after fun3', athat.data.innerData);

        await that.fun4();
        console.log('after fun1', that.data.innerData);
        await that.fun5();
        console.log('after fun2', that.data.innerData);
        await that.fun6();
        console.log('after fun3', that.data.innerData);

        await that.fun4();
        console.log('after fun1', that.data.innerData);
        await that.fun5();
        console.log('after fun2', that.data.innerData);
        await that.fun6();
        console.log('after fun3', that.data.innerData);
    },

    fun1: function () {
        let that = this;
        that.data.innerData = that.data.innerData + 1;
        console.log('in fun1, innerData', that.data.innerData);
        return 0;
    },

    fun2: function () {
        let that = this;
        that.data.innerData = that.data.innerData + 2;
        that.data.grade = 4;
        console.log('in fun2, innerData', that.data.innerData);
        return 0;
    },

    fun3: function () {
        let that = this;
        that.data.innerData = that.data.innerData + 3;
        console.log('in fun3, innerData', that.data.innerData);
        return 0;
    },

    fun4: function () {
        let that = this;
        // return new Promise((resolve, reject) => {
        db.collection('rank').where({
            uid: "asdfaf"
        }).get().then((res) => {
            //success: res => {
            that.fun1();
            //},                fail: err => {
            //that.fun1();
            //}
        });
        //return promise;
    },

    fun5: function () {
        let that = this;
        db.collection('rank').where({
            uid: "asdfaf"
        }).get().then((res) => {
            that.fun2();
        });
        return 0;
    },

    fun6: function () {
        let that = this;
        db.collection('rank').where({
            uid: "asdfaf"
        }).get().then((res) => {
            that.fun3();
        });
    },    
})

简单做一下解释,有三个基本的同步函数 fun1, fun2, fun3里边操作一个变量 innerData 作自增, 因为是要做异步操作的同步,所以在 fun4, fun5, fun6中分别加入一段带 where条件的数据库访问函数,如果成功则调用刚才fun1, fun2, fun3。

为了进行同步判断,在调用一列系待同步函数 fun4,fun5,fun5中,console.log打印出 当前的做测试的 innerData,跟函数名称, 在调用 fun4,fun5,fun6后也打印 innerData跟函数名,判断是否正确同步。

事实的输出结果有两处跟预期不相符。

第1是 主程序中所有的console.log是一齐打到终端的,并且,值也是 innerData的初始值,没有被fun1,fun2, fun3操作自增,

是不是console.log本身也是异步的,网上看了一贴子不是太理解,个人理解贴子表达的意思是不是说跟缓存有关?

第2个更关键的是,我用了网上能查到的 3种方式,尝试同步 带数据库操作的 fun4,fun5,fun6,但都没有能正确实再 顺序同步。

分别是

1、主程序 async,fun4,fun5,fun6前加await

2、使用promise方法,封装生成一个 promise对象

3、import第3方promisify库,封装fun4,fun5,fun6代码

都没能达到预期效果,输出始终不同步

0.png
请问我的3种实现方式,主要问题在哪里,应该怎样正确实现同步?

项目配置如下
0 (1).png


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

你必须先搞懂async await是什么,并不是函数前面加上await关键字就万事大吉了。
你让它await,你至少得让解释器知道,它是在wait什么?什么时候执行下一步代码,看看你的fun456,你让它wait什么了?它并没有要wait的东西啊,当然同步返回了!


fun4: async function () {
  const res = await db.collection('rank').where({uid: 'asdfaf'}).get();
  // 正常情况下判定这个res是否为空就知道用户是否注册了
  // 你代码中没有相应逻辑,给你备注在这
  // 下面几个函数需要用到返回值的话也是一样的写法
  this.fun1();
},
fun5: async function () {
  await db.collection('rank').where({uid: 'asdfaf'}).get();
  this.fun2();
},
fun6: async function () {
  await db.collection('rank').where({uid: 'asdfaf'}).get();
  this.fun3();
},

看你代码中db本身就返回一个Promise,完全没必要重新封装,不出意外按上面这样改一下就能有效果了


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...